@onekeyfe/hd-transport-react-native 1.2.0-alpha.142 → 1.2.0-alpha.144
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 +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +28 -5
- package/package.json +5 -5
- package/src/__tests__/protocolV2Link.test.ts +53 -0
- package/src/index.ts +34 -5
package/dist/index.d.ts
CHANGED
|
@@ -121,6 +121,10 @@ declare class ReactNativeBleTransport {
|
|
|
121
121
|
private deviceProtocolHints;
|
|
122
122
|
/** Protocol this device actually answered on, kept across reconnects of one session. */
|
|
123
123
|
private sessionProtocols;
|
|
124
|
+
/** Endpoints that answered a V2 probe in this transport lifetime. Survives disconnect. */
|
|
125
|
+
private confirmedProtocolV2;
|
|
126
|
+
/** First expected-V2 miss for an unconfirmed endpoint; the next miss is a stale bond. */
|
|
127
|
+
private retryableV2Mismatch;
|
|
124
128
|
/** Consecutive detections that failed while trusting sessionProtocols. */
|
|
125
129
|
private protocolReprobeFailures;
|
|
126
130
|
private protocolV2Assemblers;
|
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
|
@@ -404,6 +404,8 @@ class ReactNativeBleTransport {
|
|
|
404
404
|
this.connectionSetupTimeoutCounts = new Map();
|
|
405
405
|
this.deviceProtocolHints = new Map();
|
|
406
406
|
this.sessionProtocols = new Map();
|
|
407
|
+
this.confirmedProtocolV2 = new Set();
|
|
408
|
+
this.retryableV2Mismatch = new Set();
|
|
407
409
|
this.protocolReprobeFailures = new Map();
|
|
408
410
|
this.protocolV2Assemblers = new Map();
|
|
409
411
|
this.protocolV2FrameQueues = new Map();
|
|
@@ -937,7 +939,12 @@ class ReactNativeBleTransport {
|
|
|
937
939
|
return { uuid, protocolType };
|
|
938
940
|
}
|
|
939
941
|
catch (error) {
|
|
940
|
-
|
|
942
|
+
if ((error === null || error === void 0 ? void 0 : error.errorCode) === hdShared.HardwareErrorCode.BleDeviceBondError) {
|
|
943
|
+
yield this.disconnectUnlocked(uuid);
|
|
944
|
+
}
|
|
945
|
+
else {
|
|
946
|
+
yield this.releaseUnlocked(uuid, true);
|
|
947
|
+
}
|
|
941
948
|
throw error;
|
|
942
949
|
}
|
|
943
950
|
});
|
|
@@ -1659,6 +1666,8 @@ class ReactNativeBleTransport {
|
|
|
1659
1666
|
this.deviceProtocol.clear();
|
|
1660
1667
|
this.probingProtocols.clear();
|
|
1661
1668
|
this.sessionProtocols.clear();
|
|
1669
|
+
this.confirmedProtocolV2.clear();
|
|
1670
|
+
this.retryableV2Mismatch.clear();
|
|
1662
1671
|
this.protocolReprobeFailures.clear();
|
|
1663
1672
|
this.writeTimeoutCounts.clear();
|
|
1664
1673
|
this.connectionSetupTimeoutCounts.clear();
|
|
@@ -1671,8 +1680,16 @@ class ReactNativeBleTransport {
|
|
|
1671
1680
|
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] BLE manager destroy failed (ignored):', error);
|
|
1672
1681
|
}
|
|
1673
1682
|
}
|
|
1674
|
-
createProtocolMismatchError(expected) {
|
|
1675
|
-
|
|
1683
|
+
createProtocolMismatchError(expected, uuid) {
|
|
1684
|
+
const isStaleV2Bond = expected === 'V2' &&
|
|
1685
|
+
(this.confirmedProtocolV2.has(uuid) || this.retryableV2Mismatch.has(uuid));
|
|
1686
|
+
if (expected === 'V2' && !isStaleV2Bond) {
|
|
1687
|
+
this.retryableV2Mismatch.add(uuid);
|
|
1688
|
+
}
|
|
1689
|
+
else if (isStaleV2Bond) {
|
|
1690
|
+
this.retryableV2Mismatch.delete(uuid);
|
|
1691
|
+
}
|
|
1692
|
+
return hdShared.ERRORS.TypedError(isStaleV2Bond ? hdShared.HardwareErrorCode.BleDeviceBondError : hdShared.HardwareErrorCode.RuntimeError, `Device protocol mismatch: expected ${expected}, but device did not respond to expected protocol`);
|
|
1676
1693
|
}
|
|
1677
1694
|
createProtocolDetectionError() {
|
|
1678
1695
|
return hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleTimeoutError, 'Unable to detect BLE protocol: device did not respond to Protocol V1 GetFeatures or Protocol V2 Ping');
|
|
@@ -1712,12 +1729,14 @@ class ReactNativeBleTransport {
|
|
|
1712
1729
|
});
|
|
1713
1730
|
return 'V1';
|
|
1714
1731
|
}
|
|
1715
|
-
throw this.createProtocolMismatchError(expectedProtocol);
|
|
1732
|
+
throw this.createProtocolMismatchError(expectedProtocol, uuid);
|
|
1716
1733
|
}
|
|
1717
1734
|
if (expectedProtocol === 'V2') {
|
|
1718
1735
|
if (yield this.probeProtocolV2(uuid)) {
|
|
1719
1736
|
this.deviceProtocol.set(uuid, 'V2');
|
|
1720
1737
|
this.sessionProtocols.set(uuid, 'V2');
|
|
1738
|
+
this.confirmedProtocolV2.add(uuid);
|
|
1739
|
+
this.retryableV2Mismatch.delete(uuid);
|
|
1721
1740
|
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] protocol detected', {
|
|
1722
1741
|
deviceId: uuid,
|
|
1723
1742
|
protocol: 'V2',
|
|
@@ -1725,7 +1744,7 @@ class ReactNativeBleTransport {
|
|
|
1725
1744
|
});
|
|
1726
1745
|
return 'V2';
|
|
1727
1746
|
}
|
|
1728
|
-
throw this.createProtocolMismatchError(expectedProtocol);
|
|
1747
|
+
throw this.createProtocolMismatchError(expectedProtocol, uuid);
|
|
1729
1748
|
}
|
|
1730
1749
|
const sessionProtocol = this.sessionProtocols.get(uuid);
|
|
1731
1750
|
const reprobeFailures = (_a = this.protocolReprobeFailures.get(uuid)) !== null && _a !== void 0 ? _a : 0;
|
|
@@ -1749,6 +1768,10 @@ class ReactNativeBleTransport {
|
|
|
1749
1768
|
if (detected) {
|
|
1750
1769
|
this.deviceProtocol.set(uuid, protocol);
|
|
1751
1770
|
this.sessionProtocols.set(uuid, protocol);
|
|
1771
|
+
if (protocol === 'V2') {
|
|
1772
|
+
this.confirmedProtocolV2.add(uuid);
|
|
1773
|
+
this.retryableV2Mismatch.delete(uuid);
|
|
1774
|
+
}
|
|
1752
1775
|
this.protocolReprobeFailures.delete(uuid);
|
|
1753
1776
|
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] protocol detected', {
|
|
1754
1777
|
deviceId: uuid,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onekeyfe/hd-transport-react-native",
|
|
3
|
-
"version": "1.2.0-alpha.
|
|
3
|
+
"version": "1.2.0-alpha.144",
|
|
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.
|
|
24
|
-
"@onekeyfe/hd-shared": "1.2.0-alpha.
|
|
25
|
-
"@onekeyfe/hd-transport": "1.2.0-alpha.
|
|
23
|
+
"@onekeyfe/hd-core": "1.2.0-alpha.144",
|
|
24
|
+
"@onekeyfe/hd-shared": "1.2.0-alpha.144",
|
|
25
|
+
"@onekeyfe/hd-transport": "1.2.0-alpha.144",
|
|
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": "6240fc52a40bcad467fece58183a54f1af2631fb"
|
|
30
30
|
}
|
|
@@ -424,6 +424,59 @@ describe('ReactNativeBleTransport Protocol V2 link lifecycle', () => {
|
|
|
424
424
|
await transport.release(uuid, true);
|
|
425
425
|
});
|
|
426
426
|
|
|
427
|
+
test.each(['ios', 'android'] as const)(
|
|
428
|
+
'keeps a first expected Protocol V2 probe miss retryable on %s',
|
|
429
|
+
async platform => {
|
|
430
|
+
setPlatformOS(platform);
|
|
431
|
+
const { transport, uuid, device } = createHarness();
|
|
432
|
+
jest.spyOn(transport as any, 'probeProtocolV2').mockResolvedValue(false);
|
|
433
|
+
|
|
434
|
+
await expect(transport.acquire({ uuid, expectedProtocol: 'V2' })).rejects.toMatchObject({
|
|
435
|
+
errorCode: HardwareErrorCode.RuntimeError,
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
expect(device.cancelConnection).not.toHaveBeenCalled();
|
|
439
|
+
expect(transport.getProtocolType(uuid)).toBeUndefined();
|
|
440
|
+
}
|
|
441
|
+
);
|
|
442
|
+
|
|
443
|
+
test.each(['ios', 'android'] as const)(
|
|
444
|
+
'reports a stale bond on %s after a second expected Protocol V2 probe miss',
|
|
445
|
+
async platform => {
|
|
446
|
+
setPlatformOS(platform);
|
|
447
|
+
const { transport, uuid, device } = createHarness();
|
|
448
|
+
jest.spyOn(transport as any, 'probeProtocolV2').mockResolvedValue(false);
|
|
449
|
+
|
|
450
|
+
await expect(transport.acquire({ uuid, expectedProtocol: 'V2' })).rejects.toMatchObject({
|
|
451
|
+
errorCode: HardwareErrorCode.RuntimeError,
|
|
452
|
+
});
|
|
453
|
+
await expect(transport.acquire({ uuid, expectedProtocol: 'V2' })).rejects.toMatchObject({
|
|
454
|
+
errorCode: HardwareErrorCode.BleDeviceBondError,
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
expect(device.cancelConnection).toHaveBeenCalledTimes(1);
|
|
458
|
+
expect(transport.getProtocolType(uuid)).toBeUndefined();
|
|
459
|
+
}
|
|
460
|
+
);
|
|
461
|
+
|
|
462
|
+
test.each(['ios', 'android'] as const)(
|
|
463
|
+
'reports a stale bond on %s when a previously confirmed Protocol V2 device stops responding',
|
|
464
|
+
async platform => {
|
|
465
|
+
setPlatformOS(platform);
|
|
466
|
+
const { transport, uuid, device } = createHarness();
|
|
467
|
+
await transport.acquire({ uuid, expectedProtocol: 'V2' });
|
|
468
|
+
await transport.release(uuid, true);
|
|
469
|
+
jest.spyOn(transport as any, 'probeProtocolV2').mockResolvedValue(false);
|
|
470
|
+
|
|
471
|
+
await expect(transport.acquire({ uuid, expectedProtocol: 'V2' })).rejects.toMatchObject({
|
|
472
|
+
errorCode: HardwareErrorCode.BleDeviceBondError,
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
expect(device.cancelConnection).toHaveBeenCalled();
|
|
476
|
+
expect(transport.getProtocolType(uuid)).toBeUndefined();
|
|
477
|
+
}
|
|
478
|
+
);
|
|
479
|
+
|
|
427
480
|
test('waits for an in-flight release before reacquiring the same device', async () => {
|
|
428
481
|
const { transport, uuid } = createHarness();
|
|
429
482
|
await transport.acquire({ uuid, expectedProtocol: 'V2' });
|
package/src/index.ts
CHANGED
|
@@ -381,6 +381,12 @@ export default class ReactNativeBleTransport {
|
|
|
381
381
|
/** Protocol this device actually answered on, kept across reconnects of one session. */
|
|
382
382
|
private sessionProtocols: Map<string, ProtocolType> = new Map();
|
|
383
383
|
|
|
384
|
+
/** Endpoints that answered a V2 probe in this transport lifetime. Survives disconnect. */
|
|
385
|
+
private confirmedProtocolV2 = new Set<string>();
|
|
386
|
+
|
|
387
|
+
/** First expected-V2 miss for an unconfirmed endpoint; the next miss is a stale bond. */
|
|
388
|
+
private retryableV2Mismatch = new Set<string>();
|
|
389
|
+
|
|
384
390
|
/** Consecutive detections that failed while trusting sessionProtocols. */
|
|
385
391
|
private protocolReprobeFailures: Map<string, number> = new Map();
|
|
386
392
|
|
|
@@ -1046,7 +1052,11 @@ export default class ReactNativeBleTransport {
|
|
|
1046
1052
|
this.attachDisconnectSubscription(currentTransport, currentTransport.device, uuid);
|
|
1047
1053
|
return { uuid, protocolType };
|
|
1048
1054
|
} catch (error) {
|
|
1049
|
-
|
|
1055
|
+
if ((error as { errorCode?: unknown })?.errorCode === HardwareErrorCode.BleDeviceBondError) {
|
|
1056
|
+
await this.disconnectUnlocked(uuid);
|
|
1057
|
+
} else {
|
|
1058
|
+
await this.releaseUnlocked(uuid, true);
|
|
1059
|
+
}
|
|
1050
1060
|
throw error;
|
|
1051
1061
|
}
|
|
1052
1062
|
}
|
|
@@ -1965,6 +1975,8 @@ export default class ReactNativeBleTransport {
|
|
|
1965
1975
|
this.deviceProtocol.clear();
|
|
1966
1976
|
this.probingProtocols.clear();
|
|
1967
1977
|
this.sessionProtocols.clear();
|
|
1978
|
+
this.confirmedProtocolV2.clear();
|
|
1979
|
+
this.retryableV2Mismatch.clear();
|
|
1968
1980
|
this.protocolReprobeFailures.clear();
|
|
1969
1981
|
this.writeTimeoutCounts.clear();
|
|
1970
1982
|
this.connectionSetupTimeoutCounts.clear();
|
|
@@ -1977,9 +1989,20 @@ export default class ReactNativeBleTransport {
|
|
|
1977
1989
|
}
|
|
1978
1990
|
}
|
|
1979
1991
|
|
|
1980
|
-
private createProtocolMismatchError(expected: ProtocolType) {
|
|
1992
|
+
private createProtocolMismatchError(expected: ProtocolType, uuid: string) {
|
|
1993
|
+
// Caller `expectedProtocol: 'V2'` is not proof this endpoint already answered.
|
|
1994
|
+
// A first-connect or flaky Ping must stay retryable. A later miss after a
|
|
1995
|
+
// confirmed V2 answer, or a second miss on the same uuid, is a stale bond.
|
|
1996
|
+
const isStaleV2Bond =
|
|
1997
|
+
expected === 'V2' &&
|
|
1998
|
+
(this.confirmedProtocolV2.has(uuid) || this.retryableV2Mismatch.has(uuid));
|
|
1999
|
+
if (expected === 'V2' && !isStaleV2Bond) {
|
|
2000
|
+
this.retryableV2Mismatch.add(uuid);
|
|
2001
|
+
} else if (isStaleV2Bond) {
|
|
2002
|
+
this.retryableV2Mismatch.delete(uuid);
|
|
2003
|
+
}
|
|
1981
2004
|
return ERRORS.TypedError(
|
|
1982
|
-
HardwareErrorCode.RuntimeError,
|
|
2005
|
+
isStaleV2Bond ? HardwareErrorCode.BleDeviceBondError : HardwareErrorCode.RuntimeError,
|
|
1983
2006
|
`Device protocol mismatch: expected ${expected}, but device did not respond to expected protocol`
|
|
1984
2007
|
);
|
|
1985
2008
|
}
|
|
@@ -2035,13 +2058,15 @@ export default class ReactNativeBleTransport {
|
|
|
2035
2058
|
});
|
|
2036
2059
|
return 'V1';
|
|
2037
2060
|
}
|
|
2038
|
-
throw this.createProtocolMismatchError(expectedProtocol);
|
|
2061
|
+
throw this.createProtocolMismatchError(expectedProtocol, uuid);
|
|
2039
2062
|
}
|
|
2040
2063
|
|
|
2041
2064
|
if (expectedProtocol === 'V2') {
|
|
2042
2065
|
if (await this.probeProtocolV2(uuid)) {
|
|
2043
2066
|
this.deviceProtocol.set(uuid, 'V2');
|
|
2044
2067
|
this.sessionProtocols.set(uuid, 'V2');
|
|
2068
|
+
this.confirmedProtocolV2.add(uuid);
|
|
2069
|
+
this.retryableV2Mismatch.delete(uuid);
|
|
2045
2070
|
Log?.debug('[ReactNativeBleTransport] protocol detected', {
|
|
2046
2071
|
deviceId: uuid,
|
|
2047
2072
|
protocol: 'V2',
|
|
@@ -2049,7 +2074,7 @@ export default class ReactNativeBleTransport {
|
|
|
2049
2074
|
});
|
|
2050
2075
|
return 'V2';
|
|
2051
2076
|
}
|
|
2052
|
-
throw this.createProtocolMismatchError(expectedProtocol);
|
|
2077
|
+
throw this.createProtocolMismatchError(expectedProtocol, uuid);
|
|
2053
2078
|
}
|
|
2054
2079
|
|
|
2055
2080
|
// Protocol must be actively probed after connection. Name, PID, and descriptors only
|
|
@@ -2084,6 +2109,10 @@ export default class ReactNativeBleTransport {
|
|
|
2084
2109
|
if (detected) {
|
|
2085
2110
|
this.deviceProtocol.set(uuid, protocol);
|
|
2086
2111
|
this.sessionProtocols.set(uuid, protocol);
|
|
2112
|
+
if (protocol === 'V2') {
|
|
2113
|
+
this.confirmedProtocolV2.add(uuid);
|
|
2114
|
+
this.retryableV2Mismatch.delete(uuid);
|
|
2115
|
+
}
|
|
2087
2116
|
this.protocolReprobeFailures.delete(uuid);
|
|
2088
2117
|
Log?.debug('[ReactNativeBleTransport] protocol detected', {
|
|
2089
2118
|
deviceId: uuid,
|