@onekeyfe/hd-transport-react-native 1.2.2-alpha.12 → 1.2.2-alpha.120
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/README.md +1 -1
- package/dist/BleManager.d.ts +1 -1
- package/dist/BleManager.d.ts.map +1 -1
- package/dist/bleNativeDisconnect.d.ts +3 -0
- package/dist/bleNativeDisconnect.d.ts.map +1 -0
- package/dist/bleStaleBond.d.ts.map +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +339 -74
- package/package.json +6 -6
- package/src/BleManager.ts +73 -5
- package/src/__tests__/bleNativeDisconnect.test.ts +33 -0
- package/src/__tests__/bleStaleBond.test.ts +8 -0
- package/src/__tests__/connectTimeout.test.ts +343 -3
- package/src/__tests__/protocolV2Link.test.ts +475 -8
- package/src/__tests__/staleCallTimeout.test.ts +34 -5
- package/src/bleNativeDisconnect.ts +40 -0
- package/src/bleStaleBond.ts +3 -0
- package/src/index.ts +280 -70
package/dist/index.js
CHANGED
|
@@ -57,36 +57,73 @@ const bleLogger = {
|
|
|
57
57
|
};
|
|
58
58
|
|
|
59
59
|
const Logger = bleLogger;
|
|
60
|
+
const bondFailureReasons = {
|
|
61
|
+
1: 'authentication_failed',
|
|
62
|
+
2: 'rejected',
|
|
63
|
+
3: 'canceled',
|
|
64
|
+
4: 'device_unreachable',
|
|
65
|
+
5: 'discovery_in_progress',
|
|
66
|
+
6: 'timeout',
|
|
67
|
+
7: 'repeated_attempts',
|
|
68
|
+
8: 'remote_canceled',
|
|
69
|
+
9: 'removed',
|
|
70
|
+
};
|
|
60
71
|
const getConnectedDeviceIds = (serviceUuids) => BleUtils__default["default"].getConnectedPeripherals(serviceUuids);
|
|
61
72
|
const pairDevice = (macAddress) => BleUtils__default["default"].pairDevice(macAddress);
|
|
62
|
-
const onDeviceBondState = (bleMacAddress) => new Promise((resolve, reject) => {
|
|
73
|
+
const onDeviceBondState = (bleMacAddress, signal) => new Promise((resolve, reject) => {
|
|
74
|
+
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
75
|
+
reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceDisconnected));
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
63
78
|
const cleanup = () => {
|
|
64
79
|
if (timeout) {
|
|
65
80
|
clearTimeout(timeout);
|
|
66
81
|
}
|
|
67
82
|
if (cleanupListener)
|
|
68
83
|
cleanupListener();
|
|
84
|
+
signal === null || signal === void 0 ? void 0 : signal.removeEventListener('abort', onAbort);
|
|
85
|
+
};
|
|
86
|
+
const onAbort = () => {
|
|
87
|
+
cleanup();
|
|
88
|
+
reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceDisconnected));
|
|
69
89
|
};
|
|
90
|
+
signal === null || signal === void 0 ? void 0 : signal.addEventListener('abort', onAbort, { once: true });
|
|
70
91
|
const timeout = setTimeout(() => {
|
|
71
92
|
cleanup();
|
|
72
|
-
reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceNotBonded, '
|
|
93
|
+
reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceNotBonded, 'Bluetooth pairing timed out', {
|
|
94
|
+
phase: 'bond',
|
|
95
|
+
reason: 'timeout',
|
|
96
|
+
}));
|
|
73
97
|
}, 60 * 1000);
|
|
74
98
|
const cleanupListener = BleUtils__default["default"].onDeviceBondState(peripheral => {
|
|
75
|
-
var _a;
|
|
99
|
+
var _a, _b;
|
|
76
100
|
if (((_a = peripheral.id) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== bleMacAddress.toLowerCase()) {
|
|
77
101
|
return;
|
|
78
102
|
}
|
|
79
103
|
const { bondState } = peripheral;
|
|
80
104
|
const hasBonded = bondState.preState === 'BOND_BONDING' && bondState.state === 'BOND_BONDED';
|
|
81
|
-
const
|
|
105
|
+
const hasFailed = bondState.preState === 'BOND_BONDING' && bondState.state === 'BOND_NONE';
|
|
82
106
|
Logger.debug('onDeviceBondState bondState:', bondState);
|
|
83
107
|
if (hasBonded) {
|
|
84
108
|
cleanup();
|
|
85
109
|
resolve(peripheral);
|
|
86
110
|
}
|
|
87
|
-
else if (
|
|
111
|
+
else if (hasFailed) {
|
|
88
112
|
cleanup();
|
|
89
|
-
|
|
113
|
+
const nativeReason = 'reason' in bondState && typeof bondState.reason === 'number'
|
|
114
|
+
? bondState.reason
|
|
115
|
+
: undefined;
|
|
116
|
+
const reason = nativeReason === undefined ? 'unknown' : (_b = bondFailureReasons[nativeReason]) !== null && _b !== void 0 ? _b : 'unknown';
|
|
117
|
+
const params = Object.assign({ phase: 'bond', reason }, (nativeReason === undefined ? {} : { nativeReason }));
|
|
118
|
+
if (reason === 'timeout') {
|
|
119
|
+
reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceNotBonded, 'Bluetooth pairing timed out', params));
|
|
120
|
+
}
|
|
121
|
+
else if (reason === 'canceled') {
|
|
122
|
+
reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceBondedCanceled, 'Bluetooth pairing canceled', params));
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceNotBonded, 'Bluetooth pairing failed', params));
|
|
126
|
+
}
|
|
90
127
|
}
|
|
91
128
|
});
|
|
92
129
|
});
|
|
@@ -194,6 +231,27 @@ const subscribeBleOn = (bleManager, ms = 1000) => new Promise((resolve, reject)
|
|
|
194
231
|
}, ms);
|
|
195
232
|
});
|
|
196
233
|
|
|
234
|
+
const BLE_PLX_DEVICE_DISCONNECTED = 201;
|
|
235
|
+
const IOS_PERIPHERAL_DISCONNECTED = 7;
|
|
236
|
+
const nativeErrorText$1 = (error) => [error.reason, error.message]
|
|
237
|
+
.filter((value) => typeof value === 'string')
|
|
238
|
+
.join(' ');
|
|
239
|
+
const isNativeBleDisconnectError = (error) => {
|
|
240
|
+
if (!error || typeof error !== 'object') {
|
|
241
|
+
return false;
|
|
242
|
+
}
|
|
243
|
+
const nativeError = error;
|
|
244
|
+
return (nativeError.errorCode === BLE_PLX_DEVICE_DISCONNECTED ||
|
|
245
|
+
nativeError.iosErrorCode === IOS_PERIPHERAL_DISCONNECTED);
|
|
246
|
+
};
|
|
247
|
+
const toBleDisconnectHardwareError = (error) => {
|
|
248
|
+
if ((error === null || error === void 0 ? void 0 : error.errorCode) === hdShared.HardwareErrorCode.BleDeviceDisconnected) {
|
|
249
|
+
return error;
|
|
250
|
+
}
|
|
251
|
+
const nativeError = (error !== null && error !== void 0 ? error : {});
|
|
252
|
+
return hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceDisconnected, nativeErrorText$1(nativeError) || undefined);
|
|
253
|
+
};
|
|
254
|
+
|
|
197
255
|
const ATT_INSUFFICIENT_AUTHENTICATION = 5;
|
|
198
256
|
const ATT_INSUFFICIENT_ENCRYPTION = 15;
|
|
199
257
|
const IOS_PEER_REMOVED_PAIRING_INFORMATION = 14;
|
|
@@ -207,6 +265,8 @@ const isNativeBleStaleBondError = (error) => {
|
|
|
207
265
|
const nativeError = error;
|
|
208
266
|
if (nativeError.attErrorCode === ATT_INSUFFICIENT_AUTHENTICATION ||
|
|
209
267
|
nativeError.attErrorCode === ATT_INSUFFICIENT_ENCRYPTION ||
|
|
268
|
+
nativeError.androidErrorCode === ATT_INSUFFICIENT_AUTHENTICATION ||
|
|
269
|
+
nativeError.androidErrorCode === ATT_INSUFFICIENT_ENCRYPTION ||
|
|
210
270
|
nativeError.iosErrorCode === IOS_PEER_REMOVED_PAIRING_INFORMATION) {
|
|
211
271
|
return true;
|
|
212
272
|
}
|
|
@@ -256,6 +316,7 @@ class BleTransport {
|
|
|
256
316
|
const { check, ProtocolV1, parseConfigure } = transport__default["default"];
|
|
257
317
|
const Log = bleLogger;
|
|
258
318
|
const transportCache = {};
|
|
319
|
+
let bleManagerResetPromise;
|
|
259
320
|
const FIRMWARE_UPLOAD_WRITE_BURST_SIZE = reactNative.Platform.OS === 'ios' ? 4 : 5;
|
|
260
321
|
const FIRMWARE_UPLOAD_WRITE_PAUSE_MS = reactNative.Platform.OS === 'ios' ? 8 : 10;
|
|
261
322
|
const FIRMWARE_UPLOAD_WRITE_FLUSH_DELAY_MS = reactNative.Platform.OS === 'ios' ? 24 : 30;
|
|
@@ -314,6 +375,17 @@ const WEDGED_WRITE_MESSAGE = 'BLE write timeout after';
|
|
|
314
375
|
const isWedgedWriteError = (error) => (error === null || error === void 0 ? void 0 : error.errorCode) === hdShared.HardwareErrorCode.BleWriteCharacteristicError &&
|
|
315
376
|
typeof (error === null || error === void 0 ? void 0 : error.message) === 'string' &&
|
|
316
377
|
error.message.startsWith(WEDGED_WRITE_MESSAGE);
|
|
378
|
+
const shouldRethrowProtocolProbeError = (error) => {
|
|
379
|
+
const code = error === null || error === void 0 ? void 0 : error.errorCode;
|
|
380
|
+
return (hdShared.isBleStaleBondHardwareError(error) ||
|
|
381
|
+
isNativeBleDisconnectError(error) ||
|
|
382
|
+
code === hdShared.HardwareErrorCode.BleDeviceNotBonded ||
|
|
383
|
+
code === hdShared.HardwareErrorCode.BleDeviceBondedCanceled ||
|
|
384
|
+
code === hdShared.HardwareErrorCode.BleDeviceDisconnected ||
|
|
385
|
+
code === hdShared.HardwareErrorCode.BleCharacteristicNotifyError ||
|
|
386
|
+
code === hdShared.HardwareErrorCode.BleCharacteristicNotifyChangeFailure ||
|
|
387
|
+
code === hdShared.HardwareErrorCode.BleWriteCharacteristicError);
|
|
388
|
+
};
|
|
317
389
|
const BLE_WRITE_TIMEOUT_MANAGER_RESET_THRESHOLD = 2;
|
|
318
390
|
const DEVICE_SCAN_TIMEOUT_MS = 3000;
|
|
319
391
|
const IOS_NOTIFY_READY_DELAY_MS = 150;
|
|
@@ -404,10 +476,10 @@ const requestNegotiatedMtu = (device, stage, attempt) => __awaiter(void 0, void
|
|
|
404
476
|
}
|
|
405
477
|
});
|
|
406
478
|
const resolveNegotiatedMtu = (device) => requestNegotiatedMtu(device, 'connected', 0);
|
|
407
|
-
function remapError(error
|
|
479
|
+
function remapError(error) {
|
|
408
480
|
var _a;
|
|
409
481
|
if (error instanceof reactNativeBlePlx.BleError) {
|
|
410
|
-
if (
|
|
482
|
+
if (isNativeBleStaleBondError(error)) {
|
|
411
483
|
throw toBleStaleBondHardwareError(error);
|
|
412
484
|
}
|
|
413
485
|
if ((error === null || error === void 0 ? void 0 : error.attErrorCode) === 22) {
|
|
@@ -427,6 +499,7 @@ class ReactNativeBleTransport {
|
|
|
427
499
|
this.name = 'ReactNativeBleTransport';
|
|
428
500
|
this.configured = false;
|
|
429
501
|
this.stopped = false;
|
|
502
|
+
this.bondAbortController = new AbortController();
|
|
430
503
|
this.scanTimeout = DEVICE_SCAN_TIMEOUT_MS;
|
|
431
504
|
this.runPromise = null;
|
|
432
505
|
this.runPromiseDeviceId = null;
|
|
@@ -456,11 +529,20 @@ class ReactNativeBleTransport {
|
|
|
456
529
|
},
|
|
457
530
|
classifyError: () => 'link-fatal',
|
|
458
531
|
onLinkInvalidated: (uuid, reason) => __awaiter(this, void 0, void 0, function* () {
|
|
459
|
-
var _b;
|
|
532
|
+
var _b, _c;
|
|
460
533
|
(_b = this.protocolV2Assemblers.get(uuid)) === null || _b === void 0 ? void 0 : _b.reset();
|
|
461
534
|
this.rejectProtocolV2Frames(uuid, new Error(reason));
|
|
462
535
|
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V2 link invalidated:', uuid, reason);
|
|
463
536
|
if (reason.startsWith('Protocol V2 link-fatal error:')) {
|
|
537
|
+
if (this.probingProtocols.get(uuid) !== 'V2') {
|
|
538
|
+
const transport = transportCache[uuid];
|
|
539
|
+
try {
|
|
540
|
+
this.emitDeviceDisconnect(uuid, (_c = transport === null || transport === void 0 ? void 0 : transport.device) === null || _c === void 0 ? void 0 : _c.name, transport === null || transport === void 0 ? void 0 : transport.monitorToken);
|
|
541
|
+
}
|
|
542
|
+
catch (_d) {
|
|
543
|
+
Log === null || Log === void 0 ? void 0 : Log.error('[ReactNativeBleTransport] Protocol V2 disconnect listener failed');
|
|
544
|
+
}
|
|
545
|
+
}
|
|
464
546
|
yield this.releaseNative(uuid, true);
|
|
465
547
|
}
|
|
466
548
|
}),
|
|
@@ -472,6 +554,7 @@ class ReactNativeBleTransport {
|
|
|
472
554
|
this.androidPriorityResetTimers = new Map();
|
|
473
555
|
this.nextMonitorToken = 1;
|
|
474
556
|
this.lifecycleOperations = new Map();
|
|
557
|
+
this.scanCleanups = new Set();
|
|
475
558
|
this.scanTimeout = (_a = options.scanTimeout) !== null && _a !== void 0 ? _a : DEVICE_SCAN_TIMEOUT_MS;
|
|
476
559
|
}
|
|
477
560
|
init(logger, emitter) {
|
|
@@ -500,10 +583,38 @@ class ReactNativeBleTransport {
|
|
|
500
583
|
listen() {
|
|
501
584
|
}
|
|
502
585
|
getPlxManager() {
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
586
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
587
|
+
while (bleManagerResetPromise) {
|
|
588
|
+
yield this.waitForManagerReset();
|
|
589
|
+
}
|
|
590
|
+
if (this.stopped)
|
|
591
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceDisconnected);
|
|
592
|
+
if (!this.blePlxManager)
|
|
593
|
+
this.blePlxManager = new reactNativeBlePlx.BleManager();
|
|
594
|
+
return this.blePlxManager;
|
|
595
|
+
});
|
|
596
|
+
}
|
|
597
|
+
waitForManagerReset() {
|
|
598
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
599
|
+
if (!bleManagerResetPromise)
|
|
600
|
+
return;
|
|
601
|
+
let timeout;
|
|
602
|
+
try {
|
|
603
|
+
yield Promise.race([
|
|
604
|
+
bleManagerResetPromise,
|
|
605
|
+
new Promise((_, reject) => {
|
|
606
|
+
timeout = setTimeout(() => reject(this.createWedgedBleSetupError()), BLE_CONNECT_TIMEOUT_MS);
|
|
607
|
+
}),
|
|
608
|
+
]);
|
|
609
|
+
}
|
|
610
|
+
catch (_a) {
|
|
611
|
+
throw this.createWedgedBleSetupError();
|
|
612
|
+
}
|
|
613
|
+
finally {
|
|
614
|
+
if (timeout)
|
|
615
|
+
clearTimeout(timeout);
|
|
616
|
+
}
|
|
617
|
+
});
|
|
507
618
|
}
|
|
508
619
|
resolveCharacteristics(device) {
|
|
509
620
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -668,30 +779,55 @@ class ReactNativeBleTransport {
|
|
|
668
779
|
}
|
|
669
780
|
enumerate() {
|
|
670
781
|
return __awaiter(this, void 0, void 0, function* () {
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
if (reactNative.
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
reactNative.PermissionsAndroid.PERMISSIONS.BLUETOOTH_CONNECT,
|
|
686
|
-
reactNative.PermissionsAndroid.PERMISSIONS.BLUETOOTH_SCAN,
|
|
687
|
-
]);
|
|
688
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('requesting permissions, result: ', resultConnect);
|
|
689
|
-
if (resultConnect[reactNative.PermissionsAndroid.PERMISSIONS.BLUETOOTH_CONNECT] !== 'granted' ||
|
|
690
|
-
resultConnect[reactNative.PermissionsAndroid.PERMISSIONS.BLUETOOTH_SCAN] !== 'granted') {
|
|
691
|
-
reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BlePermissionError));
|
|
692
|
-
return;
|
|
693
|
-
}
|
|
782
|
+
const scanStartedAt = Date.now();
|
|
783
|
+
let firstDeviceMs;
|
|
784
|
+
const blePlxManager = yield this.getPlxManager();
|
|
785
|
+
yield subscribeBleOn(blePlxManager);
|
|
786
|
+
if (reactNative.Platform.OS === 'android' && reactNative.Platform.Version >= 31) {
|
|
787
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('requesting permissions, please wait...');
|
|
788
|
+
const resultConnect = yield reactNative.PermissionsAndroid.requestMultiple([
|
|
789
|
+
reactNative.PermissionsAndroid.PERMISSIONS.BLUETOOTH_CONNECT,
|
|
790
|
+
reactNative.PermissionsAndroid.PERMISSIONS.BLUETOOTH_SCAN,
|
|
791
|
+
]);
|
|
792
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('requesting permissions, result: ', resultConnect);
|
|
793
|
+
if (resultConnect[reactNative.PermissionsAndroid.PERMISSIONS.BLUETOOTH_CONNECT] !== 'granted' ||
|
|
794
|
+
resultConnect[reactNative.PermissionsAndroid.PERMISSIONS.BLUETOOTH_SCAN] !== 'granted') {
|
|
795
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BlePermissionError);
|
|
694
796
|
}
|
|
797
|
+
}
|
|
798
|
+
if (this.stopped)
|
|
799
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceDisconnected);
|
|
800
|
+
return new Promise((resolve, reject) => {
|
|
801
|
+
const deviceList = [];
|
|
802
|
+
let finished = false;
|
|
803
|
+
let scanCleanup;
|
|
804
|
+
const finishScan = (error) => {
|
|
805
|
+
if (scanCleanup)
|
|
806
|
+
return scanCleanup;
|
|
807
|
+
finished = true;
|
|
808
|
+
clearScanTimer();
|
|
809
|
+
scanCleanup = this.runNativeTeardown('scan', blePlxManager, () => __awaiter(this, void 0, void 0, function* () {
|
|
810
|
+
yield blePlxManager.stopDeviceScan();
|
|
811
|
+
})).then(() => {
|
|
812
|
+
this.scanCleanups.delete(cancelScan);
|
|
813
|
+
if (error)
|
|
814
|
+
reject(error);
|
|
815
|
+
else
|
|
816
|
+
resolve(deviceList);
|
|
817
|
+
});
|
|
818
|
+
return scanCleanup;
|
|
819
|
+
};
|
|
820
|
+
const cancelScan = () => finishScan(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceDisconnected));
|
|
821
|
+
this.scanCleanups.add(cancelScan);
|
|
822
|
+
const clearScanTimer = timer.timeout(() => {
|
|
823
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] scan completed', {
|
|
824
|
+
elapsedMs: Date.now() - scanStartedAt,
|
|
825
|
+
firstDeviceMs,
|
|
826
|
+
deviceCount: deviceList.length,
|
|
827
|
+
scanWindowMs: this.scanTimeout,
|
|
828
|
+
});
|
|
829
|
+
finishScan();
|
|
830
|
+
}, this.scanTimeout);
|
|
695
831
|
blePlxManager.startDeviceScan(getBluetoothServiceUuids(), {
|
|
696
832
|
allowDuplicates: true,
|
|
697
833
|
scanMode: reactNativeBlePlx.ScanMode.LowLatency,
|
|
@@ -700,19 +836,17 @@ class ReactNativeBleTransport {
|
|
|
700
836
|
if (error) {
|
|
701
837
|
Log === null || Log === void 0 ? void 0 : Log.debug('ble scan error: ', error);
|
|
702
838
|
if ([reactNativeBlePlx.BleErrorCode.BluetoothPoweredOff, reactNativeBlePlx.BleErrorCode.BluetoothInUnknownState].includes(error.errorCode)) {
|
|
703
|
-
|
|
839
|
+
finishScan(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BlePermissionError));
|
|
704
840
|
}
|
|
705
841
|
else if (error.errorCode === reactNativeBlePlx.BleErrorCode.BluetoothUnauthorized) {
|
|
706
|
-
|
|
842
|
+
finishScan(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleLocationError));
|
|
707
843
|
}
|
|
708
844
|
else if (error.errorCode === reactNativeBlePlx.BleErrorCode.LocationServicesDisabled) {
|
|
709
|
-
|
|
710
|
-
}
|
|
711
|
-
else if (error.errorCode === reactNativeBlePlx.BleErrorCode.ScanStartFailed) {
|
|
712
|
-
timer.timeout(() => { }, this.scanTimeout);
|
|
845
|
+
finishScan(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleLocationServicesDisabled));
|
|
713
846
|
}
|
|
847
|
+
else if (error.errorCode === reactNativeBlePlx.BleErrorCode.ScanStartFailed) ;
|
|
714
848
|
else {
|
|
715
|
-
|
|
849
|
+
finishScan(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleScanError, (_a = error.reason) !== null && _a !== void 0 ? _a : ''));
|
|
716
850
|
}
|
|
717
851
|
return;
|
|
718
852
|
}
|
|
@@ -737,6 +871,8 @@ class ReactNativeBleTransport {
|
|
|
737
871
|
});
|
|
738
872
|
}
|
|
739
873
|
});
|
|
874
|
+
if (finished)
|
|
875
|
+
return;
|
|
740
876
|
getConnectedDeviceIds(reactNative.Platform.OS === 'ios' ? getBluetoothServiceUuids() : []).then(devices => {
|
|
741
877
|
for (const device of devices) {
|
|
742
878
|
const localName = 'localName' in device && typeof device.localName === 'string'
|
|
@@ -752,10 +888,11 @@ class ReactNativeBleTransport {
|
|
|
752
888
|
addDevice(device);
|
|
753
889
|
}
|
|
754
890
|
}
|
|
755
|
-
});
|
|
891
|
+
}, error => Log === null || Log === void 0 ? void 0 : Log.debug('search connected peripheral failed:', error));
|
|
756
892
|
const addDevice = (device) => {
|
|
757
893
|
var _a;
|
|
758
|
-
if (deviceList.every(d => d.id !== device.id)) {
|
|
894
|
+
if (!finished && deviceList.every(d => d.id !== device.id)) {
|
|
895
|
+
firstDeviceMs !== null && firstDeviceMs !== void 0 ? firstDeviceMs : (firstDeviceMs = Date.now() - scanStartedAt);
|
|
759
896
|
const displayName = (_a = getDeviceDisplayName(device)) !== null && _a !== void 0 ? _a : 'Unknown BLE Device';
|
|
760
897
|
deviceList.push(Object.assign(Object.assign({}, device), { name: displayName, commType: 'ble' }));
|
|
761
898
|
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] OneKey BLE device discovered', {
|
|
@@ -765,16 +902,14 @@ class ReactNativeBleTransport {
|
|
|
765
902
|
});
|
|
766
903
|
}
|
|
767
904
|
};
|
|
768
|
-
|
|
769
|
-
blePlxManager.stopDeviceScan();
|
|
770
|
-
resolve(deviceList);
|
|
771
|
-
}, this.scanTimeout);
|
|
772
|
-
}));
|
|
905
|
+
});
|
|
773
906
|
});
|
|
774
907
|
}
|
|
775
908
|
installTransportForAcquire(uuid, device, characteristics) {
|
|
776
909
|
return __awaiter(this, void 0, void 0, function* () {
|
|
777
910
|
const { writeCharacteristic, notifyCharacteristic } = characteristics !== null && characteristics !== void 0 ? characteristics : (yield this.resolveCharacteristicsWithTimeout(uuid, device));
|
|
911
|
+
if (this.stopped)
|
|
912
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceDisconnected);
|
|
778
913
|
const transport$1 = new BleTransport(device, writeCharacteristic, notifyCharacteristic);
|
|
779
914
|
transport$1.mtuSize = typeof device.mtu === 'number' ? device.mtu : undefined;
|
|
780
915
|
const monitorToken = this.nextMonitorToken;
|
|
@@ -795,17 +930,23 @@ class ReactNativeBleTransport {
|
|
|
795
930
|
else if (reactNative.Platform.OS === 'android') {
|
|
796
931
|
yield delay(ANDROID_NOTIFY_READY_DELAY_MS);
|
|
797
932
|
}
|
|
933
|
+
if (this.stopped)
|
|
934
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceDisconnected);
|
|
798
935
|
const initialMtu = transport$1.mtuSize;
|
|
799
936
|
let refreshAttempts = 0;
|
|
800
937
|
if ((reactNative.Platform.OS === 'ios' || reactNative.Platform.OS === 'android') &&
|
|
801
938
|
shouldRefreshNegotiatedMtu(transport$1.mtuSize)) {
|
|
802
939
|
refreshAttempts += 1;
|
|
803
940
|
let refreshedDevice = yield requestNegotiatedMtu(transport$1.device, 'servicesAndNotifyReady', 1);
|
|
941
|
+
if (this.stopped)
|
|
942
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceDisconnected);
|
|
804
943
|
transport$1.device = refreshedDevice;
|
|
805
944
|
transport$1.mtuSize =
|
|
806
945
|
typeof refreshedDevice.mtu === 'number' ? refreshedDevice.mtu : transport$1.mtuSize;
|
|
807
946
|
if (shouldRefreshNegotiatedMtu(transport$1.mtuSize)) {
|
|
808
947
|
yield delay(BLE_MTU_REFRESH_RETRY_DELAY_MS);
|
|
948
|
+
if (this.stopped)
|
|
949
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceDisconnected);
|
|
809
950
|
refreshAttempts += 1;
|
|
810
951
|
refreshedDevice = yield requestNegotiatedMtu(transport$1.device, 'servicesAndNotifyReady', 2);
|
|
811
952
|
transport$1.device = refreshedDevice;
|
|
@@ -813,6 +954,8 @@ class ReactNativeBleTransport {
|
|
|
813
954
|
typeof refreshedDevice.mtu === 'number' ? refreshedDevice.mtu : transport$1.mtuSize;
|
|
814
955
|
}
|
|
815
956
|
}
|
|
957
|
+
if (this.stopped)
|
|
958
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceDisconnected);
|
|
816
959
|
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] BLE MTU ready', {
|
|
817
960
|
platform: reactNative.Platform.OS,
|
|
818
961
|
requested: getRequestedBleMtu(),
|
|
@@ -835,6 +978,8 @@ class ReactNativeBleTransport {
|
|
|
835
978
|
acquireUnlocked(input) {
|
|
836
979
|
var _a;
|
|
837
980
|
return __awaiter(this, void 0, void 0, function* () {
|
|
981
|
+
if (this.stopped)
|
|
982
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceDisconnected);
|
|
838
983
|
const { uuid, forceCleanRunPromise, expectedProtocol, skipProtocolProbe } = input;
|
|
839
984
|
const shouldMapProtocolV2StaleBond = expectedProtocol
|
|
840
985
|
? expectedProtocol === 'V2'
|
|
@@ -869,6 +1014,8 @@ class ReactNativeBleTransport {
|
|
|
869
1014
|
if (isCachedDeviceConnected &&
|
|
870
1015
|
cachedProtocol &&
|
|
871
1016
|
(!expectedProtocol || cachedProtocol === expectedProtocol)) {
|
|
1017
|
+
if (this.stopped)
|
|
1018
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceDisconnected);
|
|
872
1019
|
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] reuse cached BLE transport:', uuid, cachedProtocol);
|
|
873
1020
|
return { uuid, protocolType: cachedProtocol };
|
|
874
1021
|
}
|
|
@@ -892,15 +1039,27 @@ class ReactNativeBleTransport {
|
|
|
892
1039
|
Log === null || Log === void 0 ? void 0 : Log.debug('subscribeBleOn error: ', error);
|
|
893
1040
|
throw error;
|
|
894
1041
|
}
|
|
1042
|
+
if (this.stopped)
|
|
1043
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceDisconnected);
|
|
895
1044
|
if (reactNative.Platform.OS === 'android') {
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
1045
|
+
try {
|
|
1046
|
+
const bondState = yield pairDevice(uuid);
|
|
1047
|
+
if (bondState.bonding) {
|
|
1048
|
+
yield onDeviceBondState(uuid, this.bondAbortController.signal);
|
|
1049
|
+
}
|
|
1050
|
+
else if (!bondState.bonded) {
|
|
1051
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceNotBonded, 'device is not bonded');
|
|
1052
|
+
}
|
|
899
1053
|
}
|
|
900
|
-
|
|
901
|
-
|
|
1054
|
+
catch (error) {
|
|
1055
|
+
yield this.runNativeTeardown(uuid, blePlxManager, () => __awaiter(this, void 0, void 0, function* () {
|
|
1056
|
+
yield this.runBestEffortNativeOperation('bond failure: cancel manager connection', () => blePlxManager.cancelDeviceConnection(uuid));
|
|
1057
|
+
}));
|
|
1058
|
+
throw error;
|
|
902
1059
|
}
|
|
903
1060
|
}
|
|
1061
|
+
if (this.stopped)
|
|
1062
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceDisconnected);
|
|
904
1063
|
if (!device) {
|
|
905
1064
|
const devices = yield blePlxManager.devices([uuid]);
|
|
906
1065
|
[device] = devices;
|
|
@@ -931,7 +1090,7 @@ class ReactNativeBleTransport {
|
|
|
931
1090
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleAlreadyConnected);
|
|
932
1091
|
}
|
|
933
1092
|
else {
|
|
934
|
-
remapError(e
|
|
1093
|
+
remapError(e);
|
|
935
1094
|
}
|
|
936
1095
|
}
|
|
937
1096
|
}
|
|
@@ -955,23 +1114,44 @@ class ReactNativeBleTransport {
|
|
|
955
1114
|
try {
|
|
956
1115
|
device = yield this.connectWithTimeout(uuid, () => disconnectedDevice.connect(fallbackConnectOptions));
|
|
957
1116
|
}
|
|
958
|
-
catch (
|
|
959
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('last try to reconnect error: ',
|
|
960
|
-
if (
|
|
1117
|
+
catch (fallbackError) {
|
|
1118
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('last try to reconnect error: ', fallbackError);
|
|
1119
|
+
if (fallbackError.errorCode === reactNativeBlePlx.BleErrorCode.OperationCancelled) {
|
|
961
1120
|
Log === null || Log === void 0 ? void 0 : Log.debug('last try to reconnect');
|
|
962
1121
|
yield disconnectedDevice.cancelConnection();
|
|
963
1122
|
device = yield this.connectWithTimeout(uuid, () => disconnectedDevice.connect(fallbackConnectOptions));
|
|
964
1123
|
}
|
|
1124
|
+
else {
|
|
1125
|
+
remapError(fallbackError);
|
|
1126
|
+
}
|
|
965
1127
|
}
|
|
966
1128
|
}
|
|
967
1129
|
else {
|
|
968
|
-
remapError(e
|
|
1130
|
+
remapError(e);
|
|
969
1131
|
}
|
|
970
1132
|
}
|
|
971
1133
|
}
|
|
1134
|
+
if (this.stopped)
|
|
1135
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceDisconnected);
|
|
1136
|
+
if (reactNative.Platform.OS === 'android' && !(yield device.isConnected().catch(() => false))) {
|
|
1137
|
+
const disconnectedDevice = device;
|
|
1138
|
+
yield this.runNativeTeardown(uuid, blePlxManager, () => __awaiter(this, void 0, void 0, function* () {
|
|
1139
|
+
yield Promise.all([
|
|
1140
|
+
this.runBestEffortNativeOperation('connect failure: cancel manager connection', () => blePlxManager.cancelDeviceConnection(uuid)),
|
|
1141
|
+
this.runBestEffortNativeOperation('connect failure: cancel device connection', () => disconnectedDevice.cancelConnection()),
|
|
1142
|
+
]);
|
|
1143
|
+
}));
|
|
1144
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleConnectedError, 'device is not connected');
|
|
1145
|
+
}
|
|
1146
|
+
if (this.stopped)
|
|
1147
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceDisconnected);
|
|
972
1148
|
device = yield resolveNegotiatedMtu(device);
|
|
1149
|
+
if (this.stopped)
|
|
1150
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceDisconnected);
|
|
973
1151
|
const acquiredDevice = device;
|
|
974
1152
|
const { writeCharacteristic, notifyCharacteristic } = yield this.resolveCharacteristicsWithTimeout(uuid, acquiredDevice);
|
|
1153
|
+
if (this.stopped)
|
|
1154
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceDisconnected);
|
|
975
1155
|
const protocolHint = expectedProtocol
|
|
976
1156
|
? undefined
|
|
977
1157
|
: (_a = input.protocolHint) !== null && _a !== void 0 ? _a : this.deviceProtocolHints.get(uuid);
|
|
@@ -1014,6 +1194,8 @@ class ReactNativeBleTransport {
|
|
|
1014
1194
|
const protocolType = yield this.detectProtocol(uuid, expectedProtocol, protocolHint, () => __awaiter(this, void 0, void 0, function* () {
|
|
1015
1195
|
yield this.installTransportForAcquire(uuid, acquiredDevice);
|
|
1016
1196
|
}));
|
|
1197
|
+
if (this.stopped)
|
|
1198
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceDisconnected);
|
|
1017
1199
|
const currentTransport = transportCache[uuid];
|
|
1018
1200
|
if (!currentTransport) {
|
|
1019
1201
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.TransportNotFound);
|
|
@@ -1022,12 +1204,7 @@ class ReactNativeBleTransport {
|
|
|
1022
1204
|
return { uuid, protocolType };
|
|
1023
1205
|
}
|
|
1024
1206
|
catch (error) {
|
|
1025
|
-
|
|
1026
|
-
yield this.disconnectUnlocked(uuid);
|
|
1027
|
-
}
|
|
1028
|
-
else {
|
|
1029
|
-
yield this.releaseUnlocked(uuid, true);
|
|
1030
|
-
}
|
|
1207
|
+
yield this.disconnectUnlocked(uuid);
|
|
1031
1208
|
throw error;
|
|
1032
1209
|
}
|
|
1033
1210
|
finally {
|
|
@@ -1435,7 +1612,43 @@ class ReactNativeBleTransport {
|
|
|
1435
1612
|
});
|
|
1436
1613
|
}
|
|
1437
1614
|
stop() {
|
|
1615
|
+
var _a;
|
|
1616
|
+
if (this.stopPromise)
|
|
1617
|
+
return this.stopPromise;
|
|
1438
1618
|
this.stopped = true;
|
|
1619
|
+
this.bondAbortController.abort();
|
|
1620
|
+
const deviceIds = new Set([
|
|
1621
|
+
...this.monitorTokens.keys(),
|
|
1622
|
+
...this.sessionProtocols.keys(),
|
|
1623
|
+
...this.lifecycleOperations.keys(),
|
|
1624
|
+
...(this.runPromiseDeviceId ? [this.runPromiseDeviceId] : []),
|
|
1625
|
+
]);
|
|
1626
|
+
const scans = Array.from(this.scanCleanups, cleanup => cleanup());
|
|
1627
|
+
this.androidPriorityResetTimers.forEach(timeout => clearTimeout(timeout));
|
|
1628
|
+
this.androidPriorityResetTimers.clear();
|
|
1629
|
+
this.androidHighPriorityDevices.clear();
|
|
1630
|
+
const error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceDisconnected);
|
|
1631
|
+
(_a = this.runPromise) === null || _a === void 0 ? void 0 : _a.reject(error);
|
|
1632
|
+
this.runPromise = null;
|
|
1633
|
+
this.runPromiseDeviceId = null;
|
|
1634
|
+
deviceIds.forEach(uuid => this.rejectProtocolV2Frames(uuid, error));
|
|
1635
|
+
const manager = this.blePlxManager;
|
|
1636
|
+
const pendingConnections = manager
|
|
1637
|
+
? Array.from(this.lifecycleOperations.keys(), uuid => this.runNativeTeardown(uuid, manager, () => __awaiter(this, void 0, void 0, function* () {
|
|
1638
|
+
yield this.runBestEffortNativeOperation('stop: cancel pending device connection', () => manager.cancelDeviceConnection(uuid));
|
|
1639
|
+
})))
|
|
1640
|
+
: [];
|
|
1641
|
+
this.stopPromise = Promise.all([
|
|
1642
|
+
...scans,
|
|
1643
|
+
...pendingConnections,
|
|
1644
|
+
...Array.from(deviceIds, uuid => this.disconnect(uuid)),
|
|
1645
|
+
]).then(() => __awaiter(this, void 0, void 0, function* () {
|
|
1646
|
+
yield this.protocolV2Links.invalidateAllLinks('React Native BLE transport stopped');
|
|
1647
|
+
yield this.waitForManagerReset();
|
|
1648
|
+
this.blePlxManager = undefined;
|
|
1649
|
+
this.emitter = undefined;
|
|
1650
|
+
}));
|
|
1651
|
+
return this.stopPromise;
|
|
1439
1652
|
}
|
|
1440
1653
|
disconnect(session) {
|
|
1441
1654
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -1565,13 +1778,27 @@ class ReactNativeBleTransport {
|
|
|
1565
1778
|
});
|
|
1566
1779
|
}
|
|
1567
1780
|
cancel() {
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1781
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1782
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('transport-react-native transport cancel');
|
|
1783
|
+
const pending = this.runPromise;
|
|
1784
|
+
const deviceId = this.runPromiseDeviceId;
|
|
1785
|
+
if (pending) {
|
|
1786
|
+
pending.reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallQueueActionCancelled));
|
|
1787
|
+
if (this.runPromise === pending) {
|
|
1788
|
+
this.runPromise = null;
|
|
1789
|
+
this.runPromiseDeviceId = null;
|
|
1790
|
+
}
|
|
1791
|
+
if (deviceId)
|
|
1792
|
+
yield this.disconnect(deviceId);
|
|
1793
|
+
}
|
|
1794
|
+
});
|
|
1572
1795
|
}
|
|
1573
1796
|
connectWithTimeout(uuid, connect) {
|
|
1574
1797
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1798
|
+
if (this.stopped)
|
|
1799
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceDisconnected);
|
|
1800
|
+
const startedAt = Date.now();
|
|
1801
|
+
let succeeded = false;
|
|
1575
1802
|
let timer;
|
|
1576
1803
|
let timedOut = false;
|
|
1577
1804
|
const pending = connect();
|
|
@@ -1586,6 +1813,7 @@ class ReactNativeBleTransport {
|
|
|
1586
1813
|
}, BLE_CONNECT_TIMEOUT_MS);
|
|
1587
1814
|
}),
|
|
1588
1815
|
]);
|
|
1816
|
+
succeeded = true;
|
|
1589
1817
|
return result;
|
|
1590
1818
|
}
|
|
1591
1819
|
catch (error) {
|
|
@@ -1600,11 +1828,19 @@ class ReactNativeBleTransport {
|
|
|
1600
1828
|
finally {
|
|
1601
1829
|
if (timer)
|
|
1602
1830
|
clearTimeout(timer);
|
|
1831
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] connect completed', {
|
|
1832
|
+
connectIdSuffix: uuid.slice(-8),
|
|
1833
|
+
elapsedMs: Date.now() - startedAt,
|
|
1834
|
+
succeeded,
|
|
1835
|
+
backstopExpired: timedOut,
|
|
1836
|
+
});
|
|
1603
1837
|
}
|
|
1604
1838
|
});
|
|
1605
1839
|
}
|
|
1606
1840
|
resolveCharacteristicsWithTimeout(uuid, device) {
|
|
1607
1841
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1842
|
+
const startedAt = Date.now();
|
|
1843
|
+
let succeeded = false;
|
|
1608
1844
|
let timer;
|
|
1609
1845
|
let timedOut = false;
|
|
1610
1846
|
const pending = this.resolveCharacteristics(device);
|
|
@@ -1620,6 +1856,7 @@ class ReactNativeBleTransport {
|
|
|
1620
1856
|
}),
|
|
1621
1857
|
]);
|
|
1622
1858
|
this.connectionSetupTimeoutCounts.delete(uuid);
|
|
1859
|
+
succeeded = true;
|
|
1623
1860
|
return result;
|
|
1624
1861
|
}
|
|
1625
1862
|
catch (error) {
|
|
@@ -1634,6 +1871,12 @@ class ReactNativeBleTransport {
|
|
|
1634
1871
|
finally {
|
|
1635
1872
|
if (timer)
|
|
1636
1873
|
clearTimeout(timer);
|
|
1874
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] GATT setup completed', {
|
|
1875
|
+
connectIdSuffix: uuid.slice(-8),
|
|
1876
|
+
elapsedMs: Date.now() - startedAt,
|
|
1877
|
+
succeeded,
|
|
1878
|
+
backstopExpired: timedOut,
|
|
1879
|
+
});
|
|
1637
1880
|
}
|
|
1638
1881
|
});
|
|
1639
1882
|
}
|
|
@@ -1735,6 +1978,8 @@ class ReactNativeBleTransport {
|
|
|
1735
1978
|
}
|
|
1736
1979
|
}
|
|
1737
1980
|
resetPlxManager() {
|
|
1981
|
+
if (bleManagerResetPromise)
|
|
1982
|
+
return;
|
|
1738
1983
|
const manager = this.blePlxManager;
|
|
1739
1984
|
this.blePlxManager = undefined;
|
|
1740
1985
|
const reason = 'React Native BLE manager reset';
|
|
@@ -1776,12 +2021,20 @@ class ReactNativeBleTransport {
|
|
|
1776
2021
|
this.connectionSetupTimeoutCounts.clear();
|
|
1777
2022
|
this.monitorTokens.clear();
|
|
1778
2023
|
this.protocolV2Assemblers.clear();
|
|
2024
|
+
let reset;
|
|
1779
2025
|
try {
|
|
1780
|
-
manager === null || manager === void 0 ? void 0 : manager.destroy();
|
|
2026
|
+
reset = Promise.resolve(manager === null || manager === void 0 ? void 0 : manager.destroy());
|
|
1781
2027
|
}
|
|
1782
2028
|
catch (error) {
|
|
1783
|
-
|
|
2029
|
+
reset = Promise.reject(error);
|
|
1784
2030
|
}
|
|
2031
|
+
bleManagerResetPromise = reset;
|
|
2032
|
+
reset.then(() => {
|
|
2033
|
+
if (bleManagerResetPromise === reset)
|
|
2034
|
+
bleManagerResetPromise = undefined;
|
|
2035
|
+
}, error => {
|
|
2036
|
+
Log === null || Log === void 0 ? void 0 : Log.error('[ReactNativeBleTransport] BLE manager destroy failed:', error);
|
|
2037
|
+
});
|
|
1785
2038
|
}
|
|
1786
2039
|
createProtocolMismatchError(expected) {
|
|
1787
2040
|
return hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Device protocol mismatch: expected ${expected}, but device did not respond to expected protocol`);
|
|
@@ -1931,7 +2184,7 @@ class ReactNativeBleTransport {
|
|
|
1931
2184
|
catch (error) {
|
|
1932
2185
|
this.clearProbeProtocol(uuid, 'V1');
|
|
1933
2186
|
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V1 GetFeatures probe failed:', error);
|
|
1934
|
-
if (
|
|
2187
|
+
if (shouldRethrowProtocolProbeError(error)) {
|
|
1935
2188
|
throw error;
|
|
1936
2189
|
}
|
|
1937
2190
|
return false;
|
|
@@ -1957,7 +2210,7 @@ class ReactNativeBleTransport {
|
|
|
1957
2210
|
(_a = this.protocolV2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
|
|
1958
2211
|
this.resetProtocolV2Frames(uuid);
|
|
1959
2212
|
},
|
|
1960
|
-
shouldRethrow:
|
|
2213
|
+
shouldRethrow: shouldRethrowProtocolProbeError,
|
|
1961
2214
|
});
|
|
1962
2215
|
if (!detected) {
|
|
1963
2216
|
this.clearProbeProtocol(uuid, 'V2');
|
|
@@ -2084,6 +2337,9 @@ class ReactNativeBleTransport {
|
|
|
2084
2337
|
this.rememberStaleBondError(uuid, bondError);
|
|
2085
2338
|
throw bondError;
|
|
2086
2339
|
}
|
|
2340
|
+
if (isNativeBleDisconnectError(error)) {
|
|
2341
|
+
throw toBleDisconnectHardwareError(error);
|
|
2342
|
+
}
|
|
2087
2343
|
if (getFirmwareUploadWriteRetryType(error) !== 'congested' ||
|
|
2088
2344
|
attempt >= FIRMWARE_UPLOAD_WRITE_MAX_RETRIES) {
|
|
2089
2345
|
throw error;
|
|
@@ -2126,6 +2382,7 @@ class ReactNativeBleTransport {
|
|
|
2126
2382
|
if (!this._messages || !this._messagesV2) {
|
|
2127
2383
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.TransportNotConfigured);
|
|
2128
2384
|
}
|
|
2385
|
+
const isProtocolProbe = this.probingProtocols.get(uuid) === 'V2';
|
|
2129
2386
|
const callOptions = options;
|
|
2130
2387
|
const highThroughputWrite = transport.isProtocolV2HighThroughputCall(name);
|
|
2131
2388
|
if (highThroughputWrite) {
|
|
@@ -2166,6 +2423,14 @@ class ReactNativeBleTransport {
|
|
|
2166
2423
|
}
|
|
2167
2424
|
catch (e) {
|
|
2168
2425
|
Log === null || Log === void 0 ? void 0 : Log.error('[ReactNativeBleTransport] Protocol V2 call error:', e);
|
|
2426
|
+
if (!isProtocolProbe &&
|
|
2427
|
+
(e === null || e === void 0 ? void 0 : e.errorCode) === hdShared.HardwareErrorCode.BleTimeoutError &&
|
|
2428
|
+
!this.monitorTokens.has(uuid)) {
|
|
2429
|
+
yield this.runLifecycleOperation(uuid, () => __awaiter(this, void 0, void 0, function* () {
|
|
2430
|
+
if (!this.monitorTokens.has(uuid))
|
|
2431
|
+
yield this.disconnectUnlocked(uuid);
|
|
2432
|
+
}));
|
|
2433
|
+
}
|
|
2169
2434
|
throw e;
|
|
2170
2435
|
}
|
|
2171
2436
|
finally {
|