@onekeyfe/hd-transport-react-native 1.2.3-alpha.4 → 1.2.3-alpha.5
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/bleNativeDisconnect.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +51 -20
- package/dist/subscribeBleOn.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/__tests__/bleNativeDisconnect.test.ts +21 -0
- package/src/__tests__/connectTimeout.test.ts +38 -0
- package/src/__tests__/enumerate.test.ts +36 -1
- package/src/__tests__/subscribeBleOn.test.ts +111 -0
- package/src/bleNativeDisconnect.ts +2 -1
- package/src/index.ts +17 -13
- package/src/subscribeBleOn.ts +26 -10
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bleNativeDisconnect.d.ts","sourceRoot":"","sources":["../src/bleNativeDisconnect.ts"],"names":[],"mappings":"AAiBA,eAAO,MAAM,0BAA0B,UAAW,OAAO,KAAG,
|
|
1
|
+
{"version":3,"file":"bleNativeDisconnect.d.ts","sourceRoot":"","sources":["../src/bleNativeDisconnect.ts"],"names":[],"mappings":"AAiBA,eAAO,MAAM,0BAA0B,UAAW,OAAO,KAAG,OAW3D,CAAC;AAEF,eAAO,MAAM,4BAA4B,UAAW,OAAO,UAU1D,CAAC"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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
|
@@ -213,22 +213,42 @@ const timer = process.env.NODE_ENV === 'development'
|
|
|
213
213
|
|
|
214
214
|
const subscribeBleOn = (bleManager, ms = 1000) => new Promise((resolve, reject) => {
|
|
215
215
|
let done = false;
|
|
216
|
+
let cancelTimeout = () => undefined;
|
|
217
|
+
let removeSubscription = () => undefined;
|
|
218
|
+
const finish = (error) => {
|
|
219
|
+
if (done)
|
|
220
|
+
return;
|
|
221
|
+
done = true;
|
|
222
|
+
cancelTimeout();
|
|
223
|
+
removeSubscription();
|
|
224
|
+
if (error)
|
|
225
|
+
reject(error);
|
|
226
|
+
else
|
|
227
|
+
resolve();
|
|
228
|
+
};
|
|
216
229
|
const subscription = bleManager.onStateChange(state => {
|
|
217
230
|
if (state === 'PoweredOn') {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
231
|
+
finish();
|
|
232
|
+
}
|
|
233
|
+
else if (state === 'PoweredOff') {
|
|
234
|
+
finish(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BlePoweredOff));
|
|
235
|
+
}
|
|
236
|
+
else if (state === 'Unsupported') {
|
|
237
|
+
finish(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleUnsupported));
|
|
238
|
+
}
|
|
239
|
+
else if (state === 'Unauthorized') {
|
|
240
|
+
finish(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BlePermissionError));
|
|
224
241
|
}
|
|
225
242
|
}, true);
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
243
|
+
removeSubscription = () => subscription.remove();
|
|
244
|
+
if (done) {
|
|
245
|
+
removeSubscription();
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
cancelTimeout = timer.timeout(() => {
|
|
249
|
+
finish(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleScanError));
|
|
250
|
+
}, ms);
|
|
251
|
+
}
|
|
232
252
|
});
|
|
233
253
|
|
|
234
254
|
const BLE_PLX_DEVICE_DISCONNECTED = 201;
|
|
@@ -242,7 +262,8 @@ const isNativeBleDisconnectError = (error) => {
|
|
|
242
262
|
}
|
|
243
263
|
const nativeError = error;
|
|
244
264
|
return (nativeError.errorCode === BLE_PLX_DEVICE_DISCONNECTED ||
|
|
245
|
-
nativeError.iosErrorCode === IOS_PERIPHERAL_DISCONNECTED
|
|
265
|
+
nativeError.iosErrorCode === IOS_PERIPHERAL_DISCONNECTED ||
|
|
266
|
+
nativeErrorText$1(nativeError).toLowerCase().includes('was disconnected'));
|
|
246
267
|
};
|
|
247
268
|
const toBleDisconnectHardwareError = (error) => {
|
|
248
269
|
if ((error === null || error === void 0 ? void 0 : error.errorCode) === hdShared.HardwareErrorCode.BleDeviceDisconnected) {
|
|
@@ -545,7 +566,7 @@ const resolveNegotiatedMtu = (device, cancelTransaction) => shouldRefreshNegotia
|
|
|
545
566
|
? requestNegotiatedMtu(device, 'connected', 0, cancelTransaction)
|
|
546
567
|
: Promise.resolve({ device, timedOut: false });
|
|
547
568
|
function remapError(error) {
|
|
548
|
-
var _a;
|
|
569
|
+
var _a, _b;
|
|
549
570
|
if (error instanceof reactNativeBlePlx.BleError) {
|
|
550
571
|
if (isNativeBleStaleBondError(error)) {
|
|
551
572
|
throw toBleStaleBondHardwareError(error);
|
|
@@ -554,12 +575,13 @@ function remapError(error) {
|
|
|
554
575
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceBondError);
|
|
555
576
|
}
|
|
556
577
|
}
|
|
557
|
-
if (error
|
|
558
|
-
error
|
|
559
|
-
|
|
578
|
+
if (isNativeBleDisconnectError(error)) {
|
|
579
|
+
throw toBleDisconnectHardwareError(error);
|
|
580
|
+
}
|
|
581
|
+
if (error instanceof Error && ((_a = error.message) === null || _a === void 0 ? void 0 : _a.includes('not found'))) {
|
|
560
582
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceDisconnected);
|
|
561
583
|
}
|
|
562
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleConnectedError, (
|
|
584
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleConnectedError, (_b = error.reason) !== null && _b !== void 0 ? _b : error);
|
|
563
585
|
}
|
|
564
586
|
class ReactNativeBleTransport {
|
|
565
587
|
constructor(options) {
|
|
@@ -905,8 +927,11 @@ class ReactNativeBleTransport {
|
|
|
905
927
|
var _a, _b;
|
|
906
928
|
if (error) {
|
|
907
929
|
Log === null || Log === void 0 ? void 0 : Log.debug('ble scan error: ', error);
|
|
908
|
-
if (
|
|
909
|
-
finishScan(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.
|
|
930
|
+
if (error.errorCode === reactNativeBlePlx.BleErrorCode.BluetoothPoweredOff) {
|
|
931
|
+
finishScan(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BlePoweredOff));
|
|
932
|
+
}
|
|
933
|
+
else if (error.errorCode === reactNativeBlePlx.BleErrorCode.BluetoothUnsupported) {
|
|
934
|
+
finishScan(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleUnsupported));
|
|
910
935
|
}
|
|
911
936
|
else if (error.errorCode === reactNativeBlePlx.BleErrorCode.BluetoothUnauthorized) {
|
|
912
937
|
finishScan(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleLocationError));
|
|
@@ -2038,6 +2063,12 @@ class ReactNativeBleTransport {
|
|
|
2038
2063
|
throw this.createWedgedBleSetupError();
|
|
2039
2064
|
}
|
|
2040
2065
|
}
|
|
2066
|
+
if (isNativeBleStaleBondError(error) || hdShared.isBleStaleBondHardwareError(error)) {
|
|
2067
|
+
throw toBleStaleBondHardwareError(error);
|
|
2068
|
+
}
|
|
2069
|
+
if (isNativeBleDisconnectError(error)) {
|
|
2070
|
+
throw toBleDisconnectHardwareError(error);
|
|
2071
|
+
}
|
|
2041
2072
|
if (reactNative.Platform.OS === 'android' && isMissingGattShapeError(error)) {
|
|
2042
2073
|
this.androidGattCacheRefreshes.add(uuid);
|
|
2043
2074
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subscribeBleOn.d.ts","sourceRoot":"","sources":["../src/subscribeBleOn.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C,eAAO,MAAM,cAAc,eAAgB,aAAa,kBAAc,QAAQ,IAAI,
|
|
1
|
+
{"version":3,"file":"subscribeBleOn.d.ts","sourceRoot":"","sources":["../src/subscribeBleOn.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C,eAAO,MAAM,cAAc,eAAgB,aAAa,kBAAc,QAAQ,IAAI,CAmC9E,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onekeyfe/hd-transport-react-native",
|
|
3
|
-
"version": "1.2.3-alpha.
|
|
3
|
+
"version": "1.2.3-alpha.5",
|
|
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.3-alpha.
|
|
24
|
-
"@onekeyfe/hd-shared": "1.2.3-alpha.
|
|
25
|
-
"@onekeyfe/hd-transport": "1.2.3-alpha.
|
|
23
|
+
"@onekeyfe/hd-core": "1.2.3-alpha.5",
|
|
24
|
+
"@onekeyfe/hd-shared": "1.2.3-alpha.5",
|
|
25
|
+
"@onekeyfe/hd-transport": "1.2.3-alpha.5",
|
|
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": "ee493c3ad41a6bc7fb249fba71d4b9bf8efcced8"
|
|
30
30
|
}
|
|
@@ -30,4 +30,25 @@ describe('native BLE disconnect mapping', () => {
|
|
|
30
30
|
})
|
|
31
31
|
).toBe(false);
|
|
32
32
|
});
|
|
33
|
+
|
|
34
|
+
test('recognizes the unstructured ble-plx disconnect observed during GATT discovery', () => {
|
|
35
|
+
const nativeError = {
|
|
36
|
+
errorCode: 0,
|
|
37
|
+
message: 'BleError: Device stalled-connect-device was disconnected',
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
expect(isNativeBleDisconnectError(nativeError)).toBe(true);
|
|
41
|
+
expect(toBleDisconnectHardwareError(nativeError)).toMatchObject({
|
|
42
|
+
errorCode: HardwareErrorCode.BleDeviceDisconnected,
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test('does not infer a disconnect from an unrelated discovery failure', () => {
|
|
47
|
+
expect(
|
|
48
|
+
isNativeBleDisconnectError({
|
|
49
|
+
errorCode: 0,
|
|
50
|
+
message: 'Known OneKey service UUID not found',
|
|
51
|
+
})
|
|
52
|
+
).toBe(false);
|
|
53
|
+
});
|
|
33
54
|
});
|
|
@@ -623,6 +623,44 @@ describe('BLE connect timeout', () => {
|
|
|
623
623
|
expect(bleManager.cancelDeviceConnection).toHaveBeenCalledWith(UUID);
|
|
624
624
|
});
|
|
625
625
|
|
|
626
|
+
test.each([
|
|
627
|
+
{
|
|
628
|
+
nativeFields: { errorCode: BleErrorCode.DeviceDisconnected, iosErrorCode: 14 },
|
|
629
|
+
reason: 'Peer removed pairing information',
|
|
630
|
+
errorCode: HardwareErrorCode.BlePeerRemovedPairingInformation,
|
|
631
|
+
},
|
|
632
|
+
{
|
|
633
|
+
nativeFields: { errorCode: 0, attErrorCode: 5 },
|
|
634
|
+
reason: 'GATT_INSUF_AUTHENTICATION',
|
|
635
|
+
errorCode: HardwareErrorCode.BleDeviceBondError,
|
|
636
|
+
},
|
|
637
|
+
])(
|
|
638
|
+
'maps a stale bond during GATT discovery to canonical error $errorCode',
|
|
639
|
+
async ({ nativeFields, reason, errorCode }) => {
|
|
640
|
+
const { transport, device } = createHarness(() => Promise.resolve());
|
|
641
|
+
const nativeError = Object.assign(new Error(reason), nativeFields, { reason });
|
|
642
|
+
device.discoverAllServicesAndCharacteristics.mockRejectedValueOnce(nativeError);
|
|
643
|
+
|
|
644
|
+
await expect(
|
|
645
|
+
(transport as any).resolveCharacteristicsWithTimeout(UUID, device)
|
|
646
|
+
).rejects.toMatchObject({ errorCode });
|
|
647
|
+
}
|
|
648
|
+
);
|
|
649
|
+
|
|
650
|
+
test('normalizes an unstructured GATT disconnect instead of leaking an unknown error', async () => {
|
|
651
|
+
const { transport, device } = createHarness(() => Promise.resolve());
|
|
652
|
+
const nativeError = Object.assign(new Error(`BleError: Device ${UUID} was disconnected`), {
|
|
653
|
+
errorCode: 0,
|
|
654
|
+
});
|
|
655
|
+
device.discoverAllServicesAndCharacteristics.mockRejectedValueOnce(nativeError);
|
|
656
|
+
|
|
657
|
+
await expect(
|
|
658
|
+
(transport as any).resolveCharacteristicsWithTimeout(UUID, device)
|
|
659
|
+
).rejects.toMatchObject({
|
|
660
|
+
errorCode: HardwareErrorCode.BleDeviceDisconnected,
|
|
661
|
+
});
|
|
662
|
+
});
|
|
663
|
+
|
|
626
664
|
test('a successful GATT retry clears the timeout budget before an abandoned call settles', async () => {
|
|
627
665
|
const { transport, device, bleManager } = createHarness(() => Promise.resolve());
|
|
628
666
|
let resolveAbandonedDiscovery: (() => void) | undefined;
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { EventEmitter } from 'events';
|
|
2
2
|
|
|
3
|
+
import { BleErrorCode } from 'react-native-ble-plx';
|
|
4
|
+
import { HardwareErrorCode } from '@onekeyfe/hd-shared';
|
|
5
|
+
|
|
3
6
|
import { getConnectedDeviceIds } from '../BleManager';
|
|
4
7
|
import ReactNativeBleTransport from '../index';
|
|
5
8
|
|
|
@@ -14,7 +17,14 @@ jest.mock(
|
|
|
14
17
|
|
|
15
18
|
jest.mock('react-native-ble-plx', () => ({
|
|
16
19
|
BleError: class BleError extends Error {},
|
|
17
|
-
BleErrorCode: {
|
|
20
|
+
BleErrorCode: {
|
|
21
|
+
BluetoothUnsupported: 100,
|
|
22
|
+
BluetoothUnauthorized: 101,
|
|
23
|
+
BluetoothPoweredOff: 102,
|
|
24
|
+
BluetoothInUnknownState: 103,
|
|
25
|
+
ScanStartFailed: 600,
|
|
26
|
+
LocationServicesDisabled: 601,
|
|
27
|
+
},
|
|
18
28
|
BleManager: jest.fn(),
|
|
19
29
|
ScanMode: { LowLatency: 2 },
|
|
20
30
|
}));
|
|
@@ -31,6 +41,31 @@ jest.mock('../subscribeBleOn', () => ({
|
|
|
31
41
|
|
|
32
42
|
const ONEKEY_SERVICE_UUID = '00000001-0000-1000-8000-00805f9b34fb';
|
|
33
43
|
|
|
44
|
+
describe('ReactNativeBleTransport scan error mapping', () => {
|
|
45
|
+
test.each([
|
|
46
|
+
[BleErrorCode.BluetoothPoweredOff, HardwareErrorCode.BlePoweredOff],
|
|
47
|
+
[BleErrorCode.BluetoothUnsupported, HardwareErrorCode.BleUnsupported],
|
|
48
|
+
[BleErrorCode.BluetoothInUnknownState, HardwareErrorCode.BleScanError],
|
|
49
|
+
[BleErrorCode.BluetoothUnauthorized, HardwareErrorCode.BleLocationError],
|
|
50
|
+
])('maps native BLE error %s to hardware error %s', async (nativeCode, errorCode) => {
|
|
51
|
+
jest.mocked(getConnectedDeviceIds).mockResolvedValueOnce([]);
|
|
52
|
+
const blePlxManager = {
|
|
53
|
+
startDeviceScan: jest.fn((_serviceUUIDs, _options, listener) => {
|
|
54
|
+
queueMicrotask(() => {
|
|
55
|
+
listener({ errorCode: nativeCode, reason: 'native scan failure' }, null);
|
|
56
|
+
});
|
|
57
|
+
}),
|
|
58
|
+
stopDeviceScan: jest.fn(() => Promise.resolve()),
|
|
59
|
+
};
|
|
60
|
+
const transport = new ReactNativeBleTransport({ scanTimeout: 10_000 });
|
|
61
|
+
transport.blePlxManager = blePlxManager as never;
|
|
62
|
+
transport.init({ debug: jest.fn(), error: jest.fn() }, new EventEmitter());
|
|
63
|
+
|
|
64
|
+
await expect(transport.enumerate()).rejects.toMatchObject({ errorCode });
|
|
65
|
+
expect(blePlxManager.stopDeviceScan).toHaveBeenCalledTimes(1);
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
|
|
34
69
|
describe('ReactNativeBleTransport iOS discovery', () => {
|
|
35
70
|
test('keeps a bonded Pro2 communication peripheral after Find My changes its name', async () => {
|
|
36
71
|
jest.mocked(getConnectedDeviceIds).mockResolvedValueOnce([
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { HardwareErrorCode } from '@onekeyfe/hd-shared';
|
|
2
|
+
|
|
3
|
+
import { subscribeBleOn } from '../subscribeBleOn';
|
|
4
|
+
|
|
5
|
+
import type { BlePlxManager } from '../types';
|
|
6
|
+
|
|
7
|
+
type BleState = Parameters<Parameters<BlePlxManager['onStateChange']>[0]>[0];
|
|
8
|
+
|
|
9
|
+
const createBleManager = () => {
|
|
10
|
+
let stateListener: ((state: BleState) => void) | undefined;
|
|
11
|
+
const remove = jest.fn();
|
|
12
|
+
const bleManager = {
|
|
13
|
+
onStateChange: jest.fn(listener => {
|
|
14
|
+
stateListener = listener;
|
|
15
|
+
return { remove };
|
|
16
|
+
}),
|
|
17
|
+
} as unknown as BlePlxManager;
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
bleManager,
|
|
21
|
+
emitState: (state: BleState) => stateListener?.(state),
|
|
22
|
+
remove,
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
describe('subscribeBleOn', () => {
|
|
27
|
+
beforeAll(() => {
|
|
28
|
+
jest.useFakeTimers({ doNotFake: ['performance'] });
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
afterAll(() => {
|
|
32
|
+
jest.useRealTimers();
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
afterEach(() => {
|
|
36
|
+
jest.clearAllTimers();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test('resolves when Bluetooth is powered on', async () => {
|
|
40
|
+
const { bleManager, emitState, remove } = createBleManager();
|
|
41
|
+
const result = subscribeBleOn(bleManager);
|
|
42
|
+
|
|
43
|
+
emitState('PoweredOn');
|
|
44
|
+
|
|
45
|
+
await expect(result).resolves.toBeUndefined();
|
|
46
|
+
expect(remove).toHaveBeenCalledTimes(1);
|
|
47
|
+
expect(jest.getTimerCount()).toBe(0);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test('cleans up when the current state is emitted synchronously', async () => {
|
|
51
|
+
const remove = jest.fn();
|
|
52
|
+
const bleManager = {
|
|
53
|
+
onStateChange: jest.fn(listener => {
|
|
54
|
+
listener('PoweredOn');
|
|
55
|
+
return { remove };
|
|
56
|
+
}),
|
|
57
|
+
} as unknown as BlePlxManager;
|
|
58
|
+
|
|
59
|
+
await expect(subscribeBleOn(bleManager)).resolves.toBeUndefined();
|
|
60
|
+
expect(remove).toHaveBeenCalledTimes(1);
|
|
61
|
+
expect(jest.getTimerCount()).toBe(0);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test.each([
|
|
65
|
+
['PoweredOff', HardwareErrorCode.BlePoweredOff],
|
|
66
|
+
['Unsupported', HardwareErrorCode.BleUnsupported],
|
|
67
|
+
['Unauthorized', HardwareErrorCode.BlePermissionError],
|
|
68
|
+
] as const)('maps %s to hardware error %s', async (state, errorCode) => {
|
|
69
|
+
const { bleManager, emitState, remove } = createBleManager();
|
|
70
|
+
const result = subscribeBleOn(bleManager);
|
|
71
|
+
const rejection = expect(result).rejects.toMatchObject({ errorCode });
|
|
72
|
+
|
|
73
|
+
emitState(state);
|
|
74
|
+
|
|
75
|
+
await rejection;
|
|
76
|
+
expect(remove).toHaveBeenCalledTimes(1);
|
|
77
|
+
expect(jest.getTimerCount()).toBe(0);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test('settles only once when terminal states repeat', async () => {
|
|
81
|
+
const { bleManager, emitState, remove } = createBleManager();
|
|
82
|
+
const result = subscribeBleOn(bleManager);
|
|
83
|
+
const rejection = expect(result).rejects.toMatchObject({
|
|
84
|
+
errorCode: HardwareErrorCode.BlePoweredOff,
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
emitState('PoweredOff');
|
|
88
|
+
emitState('PoweredOn');
|
|
89
|
+
|
|
90
|
+
await rejection;
|
|
91
|
+
expect(remove).toHaveBeenCalledTimes(1);
|
|
92
|
+
expect(jest.getTimerCount()).toBe(0);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
test.each(['Unknown', 'Resetting'] as const)(
|
|
96
|
+
'reports %s as a scan error if no stable state arrives before timeout',
|
|
97
|
+
async state => {
|
|
98
|
+
const { bleManager, emitState, remove } = createBleManager();
|
|
99
|
+
const result = subscribeBleOn(bleManager, 1000);
|
|
100
|
+
const rejection = expect(result).rejects.toMatchObject({
|
|
101
|
+
errorCode: HardwareErrorCode.BleScanError,
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
emitState(state);
|
|
105
|
+
jest.advanceTimersByTime(1000);
|
|
106
|
+
|
|
107
|
+
await rejection;
|
|
108
|
+
expect(remove).toHaveBeenCalledTimes(1);
|
|
109
|
+
}
|
|
110
|
+
);
|
|
111
|
+
});
|
|
@@ -23,7 +23,8 @@ export const isNativeBleDisconnectError = (error: unknown): boolean => {
|
|
|
23
23
|
const nativeError = error as NativeBleErrorFields;
|
|
24
24
|
return (
|
|
25
25
|
nativeError.errorCode === BLE_PLX_DEVICE_DISCONNECTED ||
|
|
26
|
-
nativeError.iosErrorCode === IOS_PERIPHERAL_DISCONNECTED
|
|
26
|
+
nativeError.iosErrorCode === IOS_PERIPHERAL_DISCONNECTED ||
|
|
27
|
+
nativeErrorText(nativeError).toLowerCase().includes('was disconnected')
|
|
27
28
|
);
|
|
28
29
|
};
|
|
29
30
|
|
package/src/index.ts
CHANGED
|
@@ -175,8 +175,8 @@ const shouldRethrowProtocolProbeError = (error: unknown): boolean => {
|
|
|
175
175
|
const code = (error as { errorCode?: unknown })?.errorCode;
|
|
176
176
|
// Bonding and GATT failures are not evidence of a protocol mismatch. Preserve
|
|
177
177
|
// them instead of probing another protocol on an unusable connection.
|
|
178
|
-
// Native PLX disconnects (errorCode 201 / iOS 7
|
|
179
|
-
//
|
|
178
|
+
// Native PLX disconnects (errorCode 201 / iOS 7, or the unstructured
|
|
179
|
+
// "was disconnected" fallback) must match before Protocol V2 probing.
|
|
180
180
|
return (
|
|
181
181
|
isBleStaleBondHardwareError(error) ||
|
|
182
182
|
isNativeBleDisconnectError(error) ||
|
|
@@ -460,11 +460,11 @@ function remapError(error: IOBleErrorRemap) {
|
|
|
460
460
|
}
|
|
461
461
|
}
|
|
462
462
|
|
|
463
|
-
if (
|
|
464
|
-
error
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
) {
|
|
463
|
+
if (isNativeBleDisconnectError(error)) {
|
|
464
|
+
throw toBleDisconnectHardwareError(error);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
if (error instanceof Error && error.message?.includes('not found')) {
|
|
468
468
|
throw ERRORS.TypedError(HardwareErrorCode.BleDeviceDisconnected);
|
|
469
469
|
}
|
|
470
470
|
|
|
@@ -910,12 +910,10 @@ export default class ReactNativeBleTransport {
|
|
|
910
910
|
(error, device) => {
|
|
911
911
|
if (error) {
|
|
912
912
|
Log?.debug('ble scan error: ', error);
|
|
913
|
-
if (
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
)
|
|
917
|
-
) {
|
|
918
|
-
finishScan(ERRORS.TypedError(HardwareErrorCode.BlePermissionError));
|
|
913
|
+
if (error.errorCode === BleErrorCode.BluetoothPoweredOff) {
|
|
914
|
+
finishScan(ERRORS.TypedError(HardwareErrorCode.BlePoweredOff));
|
|
915
|
+
} else if (error.errorCode === BleErrorCode.BluetoothUnsupported) {
|
|
916
|
+
finishScan(ERRORS.TypedError(HardwareErrorCode.BleUnsupported));
|
|
919
917
|
} else if (error.errorCode === BleErrorCode.BluetoothUnauthorized) {
|
|
920
918
|
finishScan(ERRORS.TypedError(HardwareErrorCode.BleLocationError));
|
|
921
919
|
} else if (error.errorCode === BleErrorCode.LocationServicesDisabled) {
|
|
@@ -2343,6 +2341,12 @@ export default class ReactNativeBleTransport {
|
|
|
2343
2341
|
throw this.createWedgedBleSetupError();
|
|
2344
2342
|
}
|
|
2345
2343
|
}
|
|
2344
|
+
if (isNativeBleStaleBondError(error) || isBleStaleBondHardwareError(error)) {
|
|
2345
|
+
throw toBleStaleBondHardwareError(error);
|
|
2346
|
+
}
|
|
2347
|
+
if (isNativeBleDisconnectError(error)) {
|
|
2348
|
+
throw toBleDisconnectHardwareError(error);
|
|
2349
|
+
}
|
|
2346
2350
|
if (Platform.OS === 'android' && isMissingGattShapeError(error)) {
|
|
2347
2351
|
this.androidGattCacheRefreshes.add(uuid);
|
|
2348
2352
|
}
|
package/src/subscribeBleOn.ts
CHANGED
|
@@ -7,20 +7,36 @@ import type { BlePlxManager } from './types';
|
|
|
7
7
|
export const subscribeBleOn = (bleManager: BlePlxManager, ms = 1000): Promise<void> =>
|
|
8
8
|
new Promise((resolve, reject) => {
|
|
9
9
|
let done = false;
|
|
10
|
+
let cancelTimeout: () => void = () => undefined;
|
|
11
|
+
let removeSubscription: () => void = () => undefined;
|
|
12
|
+
|
|
13
|
+
const finish = (error?: Error) => {
|
|
14
|
+
if (done) return;
|
|
15
|
+
done = true;
|
|
16
|
+
cancelTimeout();
|
|
17
|
+
removeSubscription();
|
|
18
|
+
if (error) reject(error);
|
|
19
|
+
else resolve();
|
|
20
|
+
};
|
|
10
21
|
|
|
11
22
|
const subscription = bleManager.onStateChange(state => {
|
|
12
23
|
if (state === 'PoweredOn') {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
24
|
+
finish();
|
|
25
|
+
} else if (state === 'PoweredOff') {
|
|
26
|
+
finish(ERRORS.TypedError(HardwareErrorCode.BlePoweredOff));
|
|
27
|
+
} else if (state === 'Unsupported') {
|
|
28
|
+
finish(ERRORS.TypedError(HardwareErrorCode.BleUnsupported));
|
|
29
|
+
} else if (state === 'Unauthorized') {
|
|
30
|
+
finish(ERRORS.TypedError(HardwareErrorCode.BlePermissionError));
|
|
18
31
|
}
|
|
19
32
|
}, true);
|
|
33
|
+
removeSubscription = () => subscription.remove();
|
|
20
34
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
35
|
+
if (done) {
|
|
36
|
+
removeSubscription();
|
|
37
|
+
} else {
|
|
38
|
+
cancelTimeout = timer.timeout(() => {
|
|
39
|
+
finish(ERRORS.TypedError(HardwareErrorCode.BleScanError));
|
|
40
|
+
}, ms);
|
|
41
|
+
}
|
|
26
42
|
});
|