@onekeyfe/hd-transport-react-native 1.2.2-alpha.114 → 1.2.2-alpha.116
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 +74 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +274 -32
- package/package.json +5 -5
- package/src/__tests__/connectTimeout.test.ts +104 -0
- package/src/__tests__/protocolV2Link.test.ts +494 -37
- package/src/index.ts +468 -43
|
@@ -6,6 +6,9 @@ import { ERRORS, HardwareErrorCode, createDeferred } from '@onekeyfe/hd-shared';
|
|
|
6
6
|
|
|
7
7
|
import { onDeviceBondState } from '../BleManager';
|
|
8
8
|
import ReactNativeBleTransport, {
|
|
9
|
+
ANDROID_LINK_DROP_QUIET_MS,
|
|
10
|
+
ANDROID_LINK_DROP_TIMEOUT_MS,
|
|
11
|
+
ANDROID_MTU_EXCHANGE_TIMEOUT_MS,
|
|
9
12
|
BLE_CONNECT_TIMEOUT_MANAGER_RESET_THRESHOLD,
|
|
10
13
|
BLE_CONNECT_TIMEOUT_MS,
|
|
11
14
|
BLE_GATT_SETUP_TIMEOUT_MS,
|
|
@@ -641,3 +644,104 @@ describe('BLE connect timeout', () => {
|
|
|
641
644
|
expect((transport as any).connectionSetupTimeoutCounts.has(UUID)).toBe(false);
|
|
642
645
|
});
|
|
643
646
|
});
|
|
647
|
+
|
|
648
|
+
describe('Android MTU and link-drop bounds', () => {
|
|
649
|
+
beforeAll(() => {
|
|
650
|
+
jest.useFakeTimers({ doNotFake: ['setImmediate', 'performance'] });
|
|
651
|
+
});
|
|
652
|
+
|
|
653
|
+
afterAll(() => {
|
|
654
|
+
jest.useRealTimers();
|
|
655
|
+
});
|
|
656
|
+
|
|
657
|
+
afterEach(() => {
|
|
658
|
+
jest.clearAllTimers();
|
|
659
|
+
jest.restoreAllMocks();
|
|
660
|
+
Object.assign(Platform, { OS: 'ios' });
|
|
661
|
+
});
|
|
662
|
+
|
|
663
|
+
test('the bounds sit above a cold-cache discovery and the 4s GATT link idle timer', () => {
|
|
664
|
+
// Single discovery passes on a Pro 2 at MTU 23 measured up to 4.8s, a refresh plus
|
|
665
|
+
// restart 7.7s; a stuck exchange never completes, so the bound only has to clear those.
|
|
666
|
+
expect(ANDROID_MTU_EXCHANGE_TIMEOUT_MS).toBeGreaterThanOrEqual(10_000);
|
|
667
|
+
expect(ANDROID_MTU_EXCHANGE_TIMEOUT_MS).toBeLessThanOrEqual(20_000);
|
|
668
|
+
// Android keeps the LE link for 4s after the last GATT client closes.
|
|
669
|
+
expect(ANDROID_LINK_DROP_QUIET_MS).toBeGreaterThan(4000);
|
|
670
|
+
expect(ANDROID_LINK_DROP_QUIET_MS).toBeLessThanOrEqual(ANDROID_LINK_DROP_TIMEOUT_MS);
|
|
671
|
+
expect(ANDROID_LINK_DROP_TIMEOUT_MS).toBeLessThanOrEqual(10_000);
|
|
672
|
+
});
|
|
673
|
+
|
|
674
|
+
test('holds an unusable link past the idle timer even when the GATT registry is already empty', async () => {
|
|
675
|
+
Object.assign(Platform, { OS: 'android' });
|
|
676
|
+
const { transport, device, bleManager } = createHarness(() => Promise.resolve(device));
|
|
677
|
+
device.isConnected.mockResolvedValue(true);
|
|
678
|
+
Object.assign(device, { mtu: 23, requestMTU: jest.fn(() => new Promise(() => {})) });
|
|
679
|
+
let settled: Error | undefined;
|
|
680
|
+
const acquire = transport.acquire({ uuid: UUID, expectedProtocol: 'V1' }).catch(error => {
|
|
681
|
+
settled = error;
|
|
682
|
+
});
|
|
683
|
+
await flush();
|
|
684
|
+
await flush();
|
|
685
|
+
expect(device.requestMTU).toHaveBeenCalledTimes(1);
|
|
686
|
+
|
|
687
|
+
jest.advanceTimersByTime(ANDROID_MTU_EXCHANGE_TIMEOUT_MS);
|
|
688
|
+
await flush();
|
|
689
|
+
await flush();
|
|
690
|
+
expect(bleManager.cancelDeviceConnection).toHaveBeenCalledWith(UUID);
|
|
691
|
+
|
|
692
|
+
// BluetoothManager.getConnectedDevices(GATT) reports this app's GATT client, which is
|
|
693
|
+
// already closed; the LE link itself stays up for the idle timer, so the wait must not
|
|
694
|
+
// release on that signal alone.
|
|
695
|
+
expect(
|
|
696
|
+
(BleUtils as unknown as { getConnectedPeripherals: jest.Mock }).getConnectedPeripherals
|
|
697
|
+
).toHaveBeenCalled();
|
|
698
|
+
jest.advanceTimersByTime(4000);
|
|
699
|
+
await flush();
|
|
700
|
+
await flush();
|
|
701
|
+
expect(settled).toBeUndefined();
|
|
702
|
+
|
|
703
|
+
await advanceUntil(() => !!settled, ANDROID_LINK_DROP_TIMEOUT_MS);
|
|
704
|
+
await acquire;
|
|
705
|
+
expect(settled).toMatchObject({ errorCode: HardwareErrorCode.BleConnectedError });
|
|
706
|
+
});
|
|
707
|
+
|
|
708
|
+
test('a slow but successful MTU exchange completes inside the bound', async () => {
|
|
709
|
+
Object.assign(Platform, { OS: 'android' });
|
|
710
|
+
const { transport, device } = createHarness(() => Promise.resolve(device));
|
|
711
|
+
device.isConnected.mockResolvedValue(true);
|
|
712
|
+
const negotiated = { ...device, mtu: 247 };
|
|
713
|
+
Object.assign(device, {
|
|
714
|
+
mtu: 23,
|
|
715
|
+
// A cold cache makes the stack discover first; the exchange then completes late.
|
|
716
|
+
requestMTU: jest.fn(
|
|
717
|
+
() =>
|
|
718
|
+
new Promise(resolve => {
|
|
719
|
+
setTimeout(() => resolve(negotiated), 8000);
|
|
720
|
+
})
|
|
721
|
+
),
|
|
722
|
+
});
|
|
723
|
+
const [, notifyCharacteristic] = await device.characteristicsForService();
|
|
724
|
+
Object.assign(notifyCharacteristic, { monitor: jest.fn(() => ({ remove: jest.fn() })) });
|
|
725
|
+
let result: unknown;
|
|
726
|
+
let failure: Error | undefined;
|
|
727
|
+
const acquire = transport.acquire({ uuid: UUID, expectedProtocol: 'V1' }).then(
|
|
728
|
+
value => {
|
|
729
|
+
result = value;
|
|
730
|
+
},
|
|
731
|
+
error => {
|
|
732
|
+
failure = error;
|
|
733
|
+
}
|
|
734
|
+
);
|
|
735
|
+
await flush();
|
|
736
|
+
await flush();
|
|
737
|
+
expect(device.discoverAllServicesAndCharacteristics).not.toHaveBeenCalled();
|
|
738
|
+
|
|
739
|
+
jest.advanceTimersByTime(8000);
|
|
740
|
+
await advanceUntil(() => result !== undefined || failure !== undefined, 5000);
|
|
741
|
+
await acquire;
|
|
742
|
+
expect(failure).toBeUndefined();
|
|
743
|
+
expect(result).toEqual({ uuid: UUID, protocolType: 'V1' });
|
|
744
|
+
expect(device.discoverAllServicesAndCharacteristics).toHaveBeenCalledTimes(1);
|
|
745
|
+
await transport.release(UUID, true);
|
|
746
|
+
});
|
|
747
|
+
});
|