@onekeyfe/hd-transport-react-native 1.2.2-alpha.1 → 1.2.2-alpha.100

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
@@ -38,14 +38,6 @@ type BleAcquireInput = {
38
38
  protocolHint?: ProtocolType;
39
39
  };
40
40
 
41
- type FirmwareInstallBleAcquireInput = BleAcquireInput & {
42
- /**
43
- * Reuse the already-verified protocol after an expected firmware-install
44
- * disconnect. The install loader accepts status requests but may not answer
45
- * the generic protocol probe used by a normal acquire.
46
- */
47
- skipProtocolProbe?: boolean;
48
- };
49
41
  type FirmwareUploadWriteRetryType = 'congested';
50
42
  type ResolvedBleCharacteristics = {
51
43
  writeCharacteristic: Characteristic;
@@ -134,14 +126,6 @@ declare class ReactNativeBleTransport {
134
126
  private confirmedProtocolV2;
135
127
  /** Consecutive detections that failed while trusting sessionProtocols. */
136
128
  private protocolReprobeFailures;
137
- /**
138
- * Native encryption/pairing failures seen before Protocol V2 probe starts.
139
- * Pro2/Neo GATT connect can succeed on a stale iOS bond; the CCCD write then
140
- * fails with ATT 5/15. Remember it so detectProtocol fails immediately.
141
- */
142
- private staleBondErrors;
143
- /** Strict or previously confirmed V2 target while acquire installs notifications. */
144
- private acquiringProtocolV2;
145
129
  private protocolV2Assemblers;
146
130
  private protocolV2FrameQueues;
147
131
  private protocolV2FramePromises;
@@ -171,7 +155,7 @@ declare class ReactNativeBleTransport {
171
155
  */
172
156
  enumerate(): Promise<IOneKeyDevice[]>;
173
157
  private installTransportForAcquire;
174
- acquire(input: FirmwareInstallBleAcquireInput): Promise<{
158
+ acquire(input: BleAcquireInput): Promise<{
175
159
  uuid: string;
176
160
  protocolType: ProtocolType;
177
161
  }>;
@@ -232,8 +216,6 @@ declare class ReactNativeBleTransport {
232
216
  private resolveProtocolV2Frame;
233
217
  private resetProtocolV2Frames;
234
218
  private rejectProtocolV2Frames;
235
- private rememberStaleBondError;
236
- private throwIfStaleBondError;
237
219
  private readProtocolV2Frame;
238
220
  private writeProtocolV2Packet;
239
221
  private writeProtocolV2Frame;
@@ -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
@@ -194,38 +194,6 @@ const subscribeBleOn = (bleManager, ms = 1000) => new Promise((resolve, reject)
194
194
  }, ms);
195
195
  });
196
196
 
197
- const ATT_INSUFFICIENT_AUTHENTICATION = 5;
198
- const ATT_INSUFFICIENT_ENCRYPTION = 15;
199
- const IOS_PEER_REMOVED_PAIRING_INFORMATION = 14;
200
- const nativeErrorText = (error) => [error.reason, error.message]
201
- .filter((value) => typeof value === 'string')
202
- .join(' ');
203
- const isNativeBleStaleBondError = (error) => {
204
- if (!error || typeof error !== 'object') {
205
- return typeof error === 'string' ? hdShared.isBleStaleBondErrorText(error) : false;
206
- }
207
- const nativeError = error;
208
- if (nativeError.attErrorCode === ATT_INSUFFICIENT_AUTHENTICATION ||
209
- nativeError.attErrorCode === ATT_INSUFFICIENT_ENCRYPTION ||
210
- nativeError.iosErrorCode === IOS_PEER_REMOVED_PAIRING_INFORMATION) {
211
- return true;
212
- }
213
- return hdShared.isBleStaleBondErrorText(nativeErrorText(nativeError));
214
- };
215
- const toBleStaleBondHardwareError = (error) => {
216
- if (hdShared.isBleStaleBondHardwareError(error)) {
217
- return error;
218
- }
219
- const nativeError = (error !== null && error !== void 0 ? error : {});
220
- const text = nativeErrorText(nativeError);
221
- const normalizedText = text.toLowerCase();
222
- const peerRemoved = nativeError.iosErrorCode === IOS_PEER_REMOVED_PAIRING_INFORMATION ||
223
- normalizedText.includes('peer removed pairing information');
224
- return hdShared.ERRORS.TypedError(peerRemoved
225
- ? hdShared.HardwareErrorCode.BlePeerRemovedPairingInformation
226
- : hdShared.HardwareErrorCode.BleDeviceBondError, text || undefined);
227
- };
228
-
229
197
  const isHeaderChunk = (chunk) => {
230
198
  if (chunk.length < 9)
231
199
  return false;
@@ -404,11 +372,12 @@ const requestNegotiatedMtu = (device, stage, attempt) => __awaiter(void 0, void
404
372
  }
405
373
  });
406
374
  const resolveNegotiatedMtu = (device) => requestNegotiatedMtu(device, 'connected', 0);
407
- function remapError(error, mapProtocolV2StaleBond) {
375
+ function remapError(error) {
408
376
  var _a;
409
377
  if (error instanceof reactNativeBlePlx.BleError) {
410
- if (mapProtocolV2StaleBond && isNativeBleStaleBondError(error)) {
411
- throw toBleStaleBondHardwareError(error);
378
+ if (error.iosErrorCode === reactNativeBlePlx.BleATTErrorCode.UnlikelyError ||
379
+ error.reason === 'Peer removed pairing information') {
380
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BlePeerRemovedPairingInformation);
412
381
  }
413
382
  if ((error === null || error === void 0 ? void 0 : error.attErrorCode) === 22) {
414
383
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceBondError);
@@ -439,8 +408,6 @@ class ReactNativeBleTransport {
439
408
  this.sessionProtocols = new Map();
440
409
  this.confirmedProtocolV2 = new Set();
441
410
  this.protocolReprobeFailures = new Map();
442
- this.staleBondErrors = new Map();
443
- this.acquiringProtocolV2 = new Set();
444
411
  this.protocolV2Assemblers = new Map();
445
412
  this.protocolV2FrameQueues = new Map();
446
413
  this.protocolV2FramePromises = new Map();
@@ -835,46 +802,19 @@ class ReactNativeBleTransport {
835
802
  acquireUnlocked(input) {
836
803
  var _a;
837
804
  return __awaiter(this, void 0, void 0, function* () {
838
- const { uuid, forceCleanRunPromise, expectedProtocol, skipProtocolProbe } = input;
839
- const shouldMapProtocolV2StaleBond = expectedProtocol
840
- ? expectedProtocol === 'V2'
841
- : this.confirmedProtocolV2.has(uuid);
805
+ const { uuid, forceCleanRunPromise, expectedProtocol } = input;
842
806
  const cachedTransport = transportCache[uuid];
843
- if (skipProtocolProbe && !cachedTransport && this.blePlxManager) {
844
- Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] refresh uncached BLE connection for firmware install:', uuid);
845
- const manager = this.blePlxManager;
846
- yield this.runNativeTeardown(uuid, manager, () => __awaiter(this, void 0, void 0, function* () {
847
- yield this.runBestEffortNativeOperation('firmware install reconnect: cancel uncached device connection', () => manager.cancelDeviceConnection(uuid));
848
- }));
849
- }
850
807
  if (cachedTransport) {
851
- if (skipProtocolProbe) {
852
- Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] refresh cached BLE connection for firmware install:', uuid);
853
- const manager = this.blePlxManager;
854
- yield this.releaseUnlocked(uuid, true);
855
- yield this.runNativeTeardown(uuid, manager, () => __awaiter(this, void 0, void 0, function* () {
856
- const operations = [];
857
- if (manager) {
858
- operations.push(this.runBestEffortNativeOperation('firmware install reconnect: cancel device connection', () => manager.cancelDeviceConnection(uuid)));
859
- }
860
- operations.push(this.runBestEffortNativeOperation('firmware install reconnect: device cancel connection', () => cachedTransport.device.cancelConnection()));
861
- yield Promise.all(operations);
862
- }));
863
- }
864
- else {
865
- const cachedProtocol = this.deviceProtocol.get(uuid);
866
- const isCachedDeviceConnected = yield cachedTransport.device
867
- .isConnected()
868
- .catch(() => false);
869
- if (isCachedDeviceConnected &&
870
- cachedProtocol &&
871
- (!expectedProtocol || cachedProtocol === expectedProtocol)) {
872
- Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] reuse cached BLE transport:', uuid, cachedProtocol);
873
- return { uuid, protocolType: cachedProtocol };
874
- }
875
- Log === null || Log === void 0 ? void 0 : Log.debug('transport not reusable, will release: ', uuid);
876
- yield this.releaseUnlocked(uuid, true);
808
+ const cachedProtocol = this.deviceProtocol.get(uuid);
809
+ const isCachedDeviceConnected = yield cachedTransport.device.isConnected().catch(() => false);
810
+ if (isCachedDeviceConnected &&
811
+ cachedProtocol &&
812
+ (!expectedProtocol || cachedProtocol === expectedProtocol)) {
813
+ Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] reuse cached BLE transport:', uuid, cachedProtocol);
814
+ return { uuid, protocolType: cachedProtocol };
877
815
  }
816
+ Log === null || Log === void 0 ? void 0 : Log.debug('transport not reusable, will release: ', uuid);
817
+ yield this.releaseUnlocked(uuid, true);
878
818
  }
879
819
  let device = null;
880
820
  if (forceCleanRunPromise && this.runPromise) {
@@ -931,7 +871,7 @@ class ReactNativeBleTransport {
931
871
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleAlreadyConnected);
932
872
  }
933
873
  else {
934
- remapError(e, shouldMapProtocolV2StaleBond);
874
+ remapError(e);
935
875
  }
936
876
  }
937
877
  }
@@ -965,7 +905,7 @@ class ReactNativeBleTransport {
965
905
  }
966
906
  }
967
907
  else {
968
- remapError(e, shouldMapProtocolV2StaleBond);
908
+ remapError(e);
969
909
  }
970
910
  }
971
911
  }
@@ -979,38 +919,11 @@ class ReactNativeBleTransport {
979
919
  if (protocolHint) {
980
920
  this.deviceProtocolHints.set(uuid, protocolHint);
981
921
  }
982
- if (shouldMapProtocolV2StaleBond) {
983
- this.acquiringProtocolV2.add(uuid);
984
- }
922
+ yield this.installTransportForAcquire(uuid, acquiredDevice, {
923
+ writeCharacteristic,
924
+ notifyCharacteristic,
925
+ });
985
926
  try {
986
- yield this.installTransportForAcquire(uuid, acquiredDevice, {
987
- writeCharacteristic,
988
- notifyCharacteristic,
989
- });
990
- if (skipProtocolProbe) {
991
- if (!expectedProtocol) {
992
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'skipProtocolProbe requires an expected BLE protocol');
993
- }
994
- const hasConfirmedProtocol = this.sessionProtocols.get(uuid) === expectedProtocol ||
995
- (expectedProtocol === 'V2' && this.confirmedProtocolV2.has(uuid));
996
- if (!hasConfirmedProtocol) {
997
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, 'skipProtocolProbe requires a previously confirmed protocol for this BLE endpoint');
998
- }
999
- this.deviceProtocol.set(uuid, expectedProtocol);
1000
- this.sessionProtocols.set(uuid, expectedProtocol);
1001
- this.protocolReprobeFailures.delete(uuid);
1002
- Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] protocol selected without probe', {
1003
- deviceId: uuid,
1004
- protocol: expectedProtocol,
1005
- source: 'firmware-install-reconnect',
1006
- });
1007
- const currentTransport = transportCache[uuid];
1008
- if (!currentTransport) {
1009
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.TransportNotFound);
1010
- }
1011
- this.attachDisconnectSubscription(currentTransport, currentTransport.device, uuid);
1012
- return { uuid, protocolType: expectedProtocol };
1013
- }
1014
927
  const protocolType = yield this.detectProtocol(uuid, expectedProtocol, protocolHint, () => __awaiter(this, void 0, void 0, function* () {
1015
928
  yield this.installTransportForAcquire(uuid, acquiredDevice);
1016
929
  }));
@@ -1022,7 +935,7 @@ class ReactNativeBleTransport {
1022
935
  return { uuid, protocolType };
1023
936
  }
1024
937
  catch (error) {
1025
- if (hdShared.isBleStaleBondHardwareError(error)) {
938
+ if ((error === null || error === void 0 ? void 0 : error.errorCode) === hdShared.HardwareErrorCode.BleDeviceBondError) {
1026
939
  yield this.disconnectUnlocked(uuid);
1027
940
  }
1028
941
  else {
@@ -1030,16 +943,13 @@ class ReactNativeBleTransport {
1030
943
  }
1031
944
  throw error;
1032
945
  }
1033
- finally {
1034
- this.acquiringProtocolV2.delete(uuid);
1035
- }
1036
946
  });
1037
947
  }
1038
948
  _monitorCharacteristic(characteristic, uuid, monitorToken, notifyTransactionId) {
1039
949
  let bufferLength = 0;
1040
950
  let buffer$1 = [];
1041
951
  const subscription = characteristic.monitor((error, c) => {
1042
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
952
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
1043
953
  const isCurrentMonitor = this.monitorTokens.get(uuid) === monitorToken;
1044
954
  if (error) {
1045
955
  Log === null || Log === void 0 ? void 0 : Log.debug(`error monitor ${characteristic.uuid}, deviceId: ${characteristic.deviceID}: ${error}`);
@@ -1051,21 +961,19 @@ class ReactNativeBleTransport {
1051
961
  Log === null || Log === void 0 ? void 0 : Log.debug('monitor error ignored for stale transport: ', uuid, notifyTransactionId);
1052
962
  return;
1053
963
  }
1054
- if ((this.getActiveProtocol(uuid) === 'V2' || this.acquiringProtocolV2.has(uuid)) &&
1055
- isNativeBleStaleBondError(error)) {
1056
- this.rememberStaleBondError(uuid, toBleStaleBondHardwareError(error));
1057
- return;
1058
- }
1059
964
  if (this.getActiveProtocol(uuid) === 'V2') {
1060
965
  let errorCode = hdShared.HardwareErrorCode.BleCharacteristicNotifyError;
1061
966
  if ((_a = error.reason) === null || _a === void 0 ? void 0 : _a.includes('The connection has timed out unexpectedly')) {
1062
967
  errorCode = hdShared.HardwareErrorCode.BleTimeoutError;
1063
968
  }
1064
- else if (((_b = error.reason) === null || _b === void 0 ? void 0 : _b.includes('Cannot write client characteristic config descriptor')) ||
1065
- ((_c = error.reason) === null || _c === void 0 ? void 0 : _c.includes('Cannot find client characteristic config descriptor')) ||
1066
- ((_d = error.reason) === null || _d === void 0 ? void 0 : _d.includes('The handle is invalid')) ||
1067
- ((_e = error.reason) === null || _e === void 0 ? void 0 : _e.includes('Writing is not permitted')) ||
1068
- ((_f = error.reason) === null || _f === void 0 ? void 0 : _f.includes('notify change failed for device'))) {
969
+ else if ((_b = error.reason) === null || _b === void 0 ? void 0 : _b.includes('Encryption is insufficient')) {
970
+ errorCode = hdShared.HardwareErrorCode.BleDeviceBondError;
971
+ }
972
+ else if (((_c = error.reason) === null || _c === void 0 ? void 0 : _c.includes('Cannot write client characteristic config descriptor')) ||
973
+ ((_d = error.reason) === null || _d === void 0 ? void 0 : _d.includes('Cannot find client characteristic config descriptor')) ||
974
+ ((_e = error.reason) === null || _e === void 0 ? void 0 : _e.includes('The handle is invalid')) ||
975
+ ((_f = error.reason) === null || _f === void 0 ? void 0 : _f.includes('Writing is not permitted')) ||
976
+ ((_g = error.reason) === null || _g === void 0 ? void 0 : _g.includes('notify change failed for device'))) {
1069
977
  errorCode = hdShared.HardwareErrorCode.BleCharacteristicNotifyChangeFailure;
1070
978
  }
1071
979
  this.rejectProtocolV2Frames(uuid, hdShared.ERRORS.TypedError(errorCode));
@@ -1073,14 +981,17 @@ class ReactNativeBleTransport {
1073
981
  }
1074
982
  if (this.runPromise && this.runPromiseDeviceId === uuid) {
1075
983
  let ERROR = hdShared.HardwareErrorCode.BleCharacteristicNotifyError;
1076
- if ((_g = error.reason) === null || _g === void 0 ? void 0 : _g.includes('The connection has timed out unexpectedly')) {
984
+ if ((_h = error.reason) === null || _h === void 0 ? void 0 : _h.includes('The connection has timed out unexpectedly')) {
1077
985
  ERROR = hdShared.HardwareErrorCode.BleTimeoutError;
1078
986
  }
1079
- if (((_h = error.reason) === null || _h === void 0 ? void 0 : _h.includes('Cannot write client characteristic config descriptor')) ||
1080
- ((_j = error.reason) === null || _j === void 0 ? void 0 : _j.includes('Cannot find client characteristic config descriptor')) ||
1081
- ((_k = error.reason) === null || _k === void 0 ? void 0 : _k.includes('The handle is invalid')) ||
1082
- ((_l = error.reason) === null || _l === void 0 ? void 0 : _l.includes('Writing is not permitted')) ||
1083
- ((_m = error.reason) === null || _m === void 0 ? void 0 : _m.includes('notify change failed for device'))) {
987
+ if ((_j = error.reason) === null || _j === void 0 ? void 0 : _j.includes('Encryption is insufficient')) {
988
+ ERROR = hdShared.HardwareErrorCode.BleDeviceBondError;
989
+ }
990
+ if (((_k = error.reason) === null || _k === void 0 ? void 0 : _k.includes('Cannot write client characteristic config descriptor')) ||
991
+ ((_l = error.reason) === null || _l === void 0 ? void 0 : _l.includes('Cannot find client characteristic config descriptor')) ||
992
+ ((_m = error.reason) === null || _m === void 0 ? void 0 : _m.includes('The handle is invalid')) ||
993
+ ((_o = error.reason) === null || _o === void 0 ? void 0 : _o.includes('Writing is not permitted')) ||
994
+ ((_p = error.reason) === null || _p === void 0 ? void 0 : _p.includes('notify change failed for device'))) {
1084
995
  const notifyError = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleCharacteristicNotifyChangeFailure);
1085
996
  this.runPromise.reject(notifyError);
1086
997
  Log === null || Log === void 0 ? void 0 : Log.debug(`${hdShared.HardwareErrorCode.BleCharacteristicNotifyChangeFailure} ${error.message} ${error.reason}`);
@@ -1122,7 +1033,7 @@ class ReactNativeBleTransport {
1122
1033
  bufferLength = 0;
1123
1034
  buffer$1 = [];
1124
1035
  if (this.runPromiseDeviceId === uuid) {
1125
- (_o = this.runPromise) === null || _o === void 0 ? void 0 : _o.resolve(value.toString('hex'));
1036
+ (_q = this.runPromise) === null || _q === void 0 ? void 0 : _q.resolve(value.toString('hex'));
1126
1037
  }
1127
1038
  }
1128
1039
  }
@@ -1133,7 +1044,7 @@ class ReactNativeBleTransport {
1133
1044
  this.rejectProtocolV2Frames(uuid, notifyError);
1134
1045
  }
1135
1046
  else if (this.runPromiseDeviceId === uuid) {
1136
- (_p = this.runPromise) === null || _p === void 0 ? void 0 : _p.reject(notifyError);
1047
+ (_r = this.runPromise) === null || _r === void 0 ? void 0 : _r.reject(notifyError);
1137
1048
  }
1138
1049
  }
1139
1050
  }, notifyTransactionId);
@@ -1187,8 +1098,6 @@ class ReactNativeBleTransport {
1187
1098
  this.protocolV2HighVolumeLogSignatures.delete(uuid);
1188
1099
  this.deviceProtocol.delete(uuid);
1189
1100
  this.probingProtocols.delete(uuid);
1190
- this.staleBondErrors.delete(uuid);
1191
- this.acquiringProtocolV2.delete(uuid);
1192
1101
  (_e = this.protocolV2Assemblers.get(uuid)) === null || _e === void 0 ? void 0 : _e.reset();
1193
1102
  this.protocolV2Assemblers.delete(uuid);
1194
1103
  this.resetProtocolV2Frames(uuid);
@@ -1474,7 +1383,6 @@ class ReactNativeBleTransport {
1474
1383
  }
1475
1384
  this.deviceProtocol.delete(session);
1476
1385
  this.probingProtocols.delete(session);
1477
- this.staleBondErrors.delete(session);
1478
1386
  this.deviceProtocolHints.delete(session);
1479
1387
  this.sessionProtocols.delete(session);
1480
1388
  this.protocolReprobeFailures.delete(session);
@@ -1653,8 +1561,6 @@ class ReactNativeBleTransport {
1653
1561
  }
1654
1562
  this.deviceProtocol.delete(uuid);
1655
1563
  this.probingProtocols.delete(uuid);
1656
- this.staleBondErrors.delete(uuid);
1657
- this.acquiringProtocolV2.delete(uuid);
1658
1564
  this.protocolV2Assemblers.delete(uuid);
1659
1565
  this.resetProtocolV2Frames(uuid);
1660
1566
  if (timeouts >= BLE_CONNECT_TIMEOUT_MANAGER_RESET_THRESHOLD) {
@@ -1724,8 +1630,6 @@ class ReactNativeBleTransport {
1724
1630
  }
1725
1631
  this.deviceProtocol.delete(uuid);
1726
1632
  this.probingProtocols.delete(uuid);
1727
- this.staleBondErrors.delete(uuid);
1728
- this.acquiringProtocolV2.delete(uuid);
1729
1633
  this.protocolV2Assemblers.delete(uuid);
1730
1634
  this.resetProtocolV2Frames(uuid);
1731
1635
  if (timeouts >= BLE_WRITE_TIMEOUT_MANAGER_RESET_THRESHOLD) {
@@ -1768,9 +1672,8 @@ class ReactNativeBleTransport {
1768
1672
  });
1769
1673
  this.deviceProtocol.clear();
1770
1674
  this.probingProtocols.clear();
1771
- this.staleBondErrors.clear();
1772
- this.acquiringProtocolV2.clear();
1773
1675
  this.sessionProtocols.clear();
1676
+ this.confirmedProtocolV2.clear();
1774
1677
  this.protocolReprobeFailures.clear();
1775
1678
  this.writeTimeoutCounts.clear();
1776
1679
  this.connectionSetupTimeoutCounts.clear();
@@ -1783,8 +1686,9 @@ class ReactNativeBleTransport {
1783
1686
  Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] BLE manager destroy failed (ignored):', error);
1784
1687
  }
1785
1688
  }
1786
- createProtocolMismatchError(expected) {
1787
- return hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Device protocol mismatch: expected ${expected}, but device did not respond to expected protocol`);
1689
+ createProtocolMismatchError(expected, uuid) {
1690
+ const isStaleV2Bond = expected === 'V2' && this.confirmedProtocolV2.has(uuid);
1691
+ return hdShared.ERRORS.TypedError(isStaleV2Bond ? hdShared.HardwareErrorCode.BleDeviceBondError : hdShared.HardwareErrorCode.RuntimeError, `Device protocol mismatch: expected ${expected}, but device did not respond to expected protocol`);
1788
1692
  }
1789
1693
  createProtocolDetectionError() {
1790
1694
  return hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleTimeoutError, 'Unable to detect BLE protocol: device did not respond to Protocol V1 GetFeatures or Protocol V2 Ping');
@@ -1804,17 +1708,27 @@ class ReactNativeBleTransport {
1804
1708
  detectProtocol(uuid, expectedProtocol, protocolHint, rebuildTransport) {
1805
1709
  var _a;
1806
1710
  return __awaiter(this, void 0, void 0, function* () {
1807
- if (expectedProtocol === 'V1') {
1808
- this.deviceProtocol.set(uuid, 'V1');
1711
+ if (reactNative.Platform.OS === 'ios' && expectedProtocol === 'V1') {
1712
+ this.deviceProtocol.set(uuid, expectedProtocol);
1809
1713
  Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] protocol selected', {
1810
1714
  deviceId: uuid,
1811
- protocol: 'V1',
1715
+ protocol: expectedProtocol,
1812
1716
  source: 'expected',
1813
1717
  });
1814
- return 'V1';
1718
+ return expectedProtocol;
1815
1719
  }
1816
- if (expectedProtocol === 'V2' || this.acquiringProtocolV2.has(uuid)) {
1817
- this.throwIfStaleBondError(uuid);
1720
+ if (expectedProtocol === 'V1') {
1721
+ if (yield this.probeProtocolV1(uuid)) {
1722
+ this.deviceProtocol.set(uuid, 'V1');
1723
+ this.sessionProtocols.set(uuid, 'V1');
1724
+ Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] protocol detected', {
1725
+ deviceId: uuid,
1726
+ protocol: 'V1',
1727
+ source: 'expected',
1728
+ });
1729
+ return 'V1';
1730
+ }
1731
+ throw this.createProtocolMismatchError(expectedProtocol, uuid);
1818
1732
  }
1819
1733
  if (expectedProtocol === 'V2') {
1820
1734
  if (yield this.probeProtocolV2(uuid)) {
@@ -1828,7 +1742,7 @@ class ReactNativeBleTransport {
1828
1742
  });
1829
1743
  return 'V2';
1830
1744
  }
1831
- throw this.createProtocolMismatchError(expectedProtocol);
1745
+ throw this.createProtocolMismatchError(expectedProtocol, uuid);
1832
1746
  }
1833
1747
  const sessionProtocol = this.sessionProtocols.get(uuid);
1834
1748
  const reprobeFailures = (_a = this.protocolReprobeFailures.get(uuid)) !== null && _a !== void 0 ? _a : 0;
@@ -1946,7 +1860,6 @@ class ReactNativeBleTransport {
1946
1860
  }
1947
1861
  this.probingProtocols.set(uuid, 'V2');
1948
1862
  (_a = this.protocolV2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
1949
- this.throwIfStaleBondError(uuid);
1950
1863
  const detected = yield transport.probeProtocolV2({
1951
1864
  call: (name, data, options) => this.callProtocolV2(uuid, name, data, options),
1952
1865
  timeoutMs: PROTOCOL_V2_PROBE_TIMEOUT_MS,
@@ -1957,7 +1870,6 @@ class ReactNativeBleTransport {
1957
1870
  (_a = this.protocolV2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
1958
1871
  this.resetProtocolV2Frames(uuid);
1959
1872
  },
1960
- shouldRethrow: hdShared.isBleStaleBondHardwareError,
1961
1873
  });
1962
1874
  if (!detected) {
1963
1875
  this.clearProbeProtocol(uuid, 'V2');
@@ -2018,19 +1930,6 @@ class ReactNativeBleTransport {
2018
1930
  framePromise.reject(error);
2019
1931
  }
2020
1932
  }
2021
- rememberStaleBondError(uuid, error) {
2022
- this.staleBondErrors.set(uuid, error);
2023
- this.rejectProtocolV2Frames(uuid, error);
2024
- if (this.runPromise && this.runPromiseDeviceId === uuid) {
2025
- this.runPromise.reject(error);
2026
- }
2027
- }
2028
- throwIfStaleBondError(uuid) {
2029
- const error = this.staleBondErrors.get(uuid);
2030
- if (error) {
2031
- throw error;
2032
- }
2033
- }
2034
1933
  readProtocolV2Frame(uuid) {
2035
1934
  return __awaiter(this, void 0, void 0, function* () {
2036
1935
  const queuedFrame = this.getProtocolV2FrameQueue(uuid).shift();
@@ -2079,11 +1978,6 @@ class ReactNativeBleTransport {
2079
1978
  return;
2080
1979
  }
2081
1980
  catch (error) {
2082
- if (isNativeBleStaleBondError(error) || hdShared.isBleStaleBondHardwareError(error)) {
2083
- const bondError = toBleStaleBondHardwareError(error);
2084
- this.rememberStaleBondError(uuid, bondError);
2085
- throw bondError;
2086
- }
2087
1981
  if (getFirmwareUploadWriteRetryType(error) !== 'congested' ||
2088
1982
  attempt >= FIRMWARE_UPLOAD_WRITE_MAX_RETRIES) {
2089
1983
  throw error;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/hd-transport-react-native",
3
- "version": "1.2.2-alpha.1",
3
+ "version": "1.2.2-alpha.100",
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.2-alpha.1",
24
- "@onekeyfe/hd-shared": "1.2.2-alpha.1",
25
- "@onekeyfe/hd-transport": "1.2.2-alpha.1",
23
+ "@onekeyfe/hd-core": "1.2.2-alpha.100",
24
+ "@onekeyfe/hd-shared": "1.2.2-alpha.100",
25
+ "@onekeyfe/hd-transport": "1.2.2-alpha.100",
26
26
  "@onekeyfe/react-native-ble-utils": "^0.1.6",
27
27
  "react-native-ble-plx": "3.5.1"
28
28
  },
29
- "gitHead": "66f45610d36e06a46ac82cd49a4b0e1a128f19d4"
29
+ "gitHead": "c40dad085297b0e3cc2020bd218c146dff6ed3e1"
30
30
  }
@@ -109,11 +109,9 @@ const schemas = {
109
109
  const createHarness = ({
110
110
  deviceName = 'OneKey Pro 2',
111
111
  isWritableWithResponse = true,
112
- monitorError,
113
112
  }: {
114
113
  deviceName?: string;
115
114
  isWritableWithResponse?: boolean;
116
- monitorError?: (Error & { reason?: string; attErrorCode?: number; iosErrorCode?: number }) | null;
117
115
  } = {}) => {
118
116
  const uuid = 'rn-pro2-id';
119
117
  const sentSeqs: number[] = [];
@@ -132,9 +130,6 @@ const createHarness = ({
132
130
  isNotifiable: true,
133
131
  monitor: jest.fn(callback => {
134
132
  notifyCallback = callback;
135
- if (monitorError) {
136
- queueMicrotask(() => callback(monitorError, null));
137
- }
138
133
  return { remove: jest.fn() };
139
134
  }),
140
135
  };
@@ -410,22 +405,6 @@ describe('ReactNativeBleTransport Protocol V2 link lifecycle', () => {
410
405
  await transport.release(uuid, true);
411
406
  });
412
407
 
413
- test('keeps native stale-bond write mapping out of Protocol V1 calls', async () => {
414
- const { transport, uuid, writeCharacteristic } = createV1Harness();
415
- const nativeError = Object.assign(new Error('Encryption is insufficient'), {
416
- attErrorCode: 15,
417
- reason: 'Encryption is insufficient',
418
- });
419
-
420
- await transport.acquire({ uuid, expectedProtocol: 'V1' });
421
- writeCharacteristic.writeWithResponse.mockRejectedValueOnce(nativeError);
422
-
423
- await expect(transport.call(uuid, 'Initialize', {}, { timeoutMs: 50 })).rejects.toMatchObject({
424
- errorCode: HardwareErrorCode.BleWriteCharacteristicError,
425
- });
426
- await transport.release(uuid, true);
427
- });
428
-
429
408
  test('detects Protocol V2 on iOS without using the BLE name as a protocol hint', async () => {
430
409
  const { transport, uuid, device, sentSeqs, writeCharacteristic } = createHarness({
431
410
  deviceName: 'Pro2 6E9E',
@@ -445,93 +424,6 @@ describe('ReactNativeBleTransport Protocol V2 link lifecycle', () => {
445
424
  await transport.release(uuid, true);
446
425
  });
447
426
 
448
- test('physically refreshes an uncached Protocol V2 firmware install link without Ping', async () => {
449
- const { transport, uuid, device, bleManager, writeCharacteristic } = createHarness();
450
- const probeProtocolV2 = jest.spyOn(transport as any, 'probeProtocolV2');
451
- (transport as any).sessionProtocols.set(uuid, 'V2');
452
- device.connect = jest.fn().mockResolvedValue(device);
453
- device.isConnected.mockResolvedValueOnce(false);
454
-
455
- await expect(
456
- transport.acquire({ uuid, expectedProtocol: 'V2', skipProtocolProbe: true })
457
- ).resolves.toEqual({
458
- uuid,
459
- protocolType: 'V2',
460
- });
461
-
462
- expect(bleManager.cancelDeviceConnection).toHaveBeenCalledWith(uuid);
463
- expect(device.cancelConnection).not.toHaveBeenCalled();
464
- expect(device.connect).toHaveBeenCalled();
465
- expect(probeProtocolV2).not.toHaveBeenCalled();
466
- expect(writeCharacteristic.writeWithResponse).not.toHaveBeenCalled();
467
- expect(writeCharacteristic.writeWithoutResponse).not.toHaveBeenCalled();
468
- expect(transport.getProtocolType(uuid)).toBe('V2');
469
- await transport.release(uuid, true);
470
- });
471
-
472
- test('refreshes a cached firmware install connection instead of trusting GATT state', async () => {
473
- const { transport, uuid, device, bleManager, writeCharacteristic } = createHarness();
474
- const probeProtocolV2 = jest.spyOn(transport as any, 'probeProtocolV2');
475
-
476
- await transport.acquire({ uuid, expectedProtocol: 'V2' });
477
- device.connect = jest.fn().mockResolvedValue(device);
478
- device.isConnected.mockResolvedValueOnce(false);
479
- writeCharacteristic.writeWithResponse.mockClear();
480
- writeCharacteristic.writeWithoutResponse.mockClear();
481
-
482
- await expect(
483
- transport.acquire({ uuid, expectedProtocol: 'V2', skipProtocolProbe: true })
484
- ).resolves.toEqual({
485
- uuid,
486
- protocolType: 'V2',
487
- });
488
-
489
- expect(bleManager.cancelDeviceConnection).toHaveBeenCalledWith(uuid);
490
- expect(device.cancelConnection).toHaveBeenCalled();
491
- expect(device.connect).toHaveBeenCalled();
492
- expect(probeProtocolV2).toHaveBeenCalledTimes(1);
493
- expect(writeCharacteristic.writeWithResponse).not.toHaveBeenCalled();
494
- expect(writeCharacteristic.writeWithoutResponse).not.toHaveBeenCalled();
495
- await transport.release(uuid, true);
496
- });
497
-
498
- test('rejects no-probe acquire before the BLE endpoint has confirmed a protocol', async () => {
499
- const { transport, uuid } = createHarness();
500
-
501
- await expect(
502
- transport.acquire({ uuid, expectedProtocol: 'V2', skipProtocolProbe: true })
503
- ).rejects.toThrow('previously confirmed protocol');
504
-
505
- expect(transport.getProtocolType(uuid)).toBeUndefined();
506
- });
507
-
508
- test('keeps confirmed V2 authorization across a BLE manager reset', async () => {
509
- const { transport, uuid, device, bleManager, writeCharacteristic } = createHarness();
510
- const probeProtocolV2 = jest.spyOn(transport as any, 'probeProtocolV2');
511
-
512
- await transport.acquire({ uuid, expectedProtocol: 'V2' });
513
- expect(probeProtocolV2).toHaveBeenCalledTimes(1);
514
-
515
- (transport as any).resetPlxManager();
516
- transport.blePlxManager = bleManager as any;
517
- device.connect = jest.fn().mockResolvedValue(device);
518
- device.isConnected.mockResolvedValueOnce(false);
519
- writeCharacteristic.writeWithResponse.mockClear();
520
- writeCharacteristic.writeWithoutResponse.mockClear();
521
-
522
- await expect(
523
- transport.acquire({ uuid, expectedProtocol: 'V2', skipProtocolProbe: true })
524
- ).resolves.toEqual({
525
- uuid,
526
- protocolType: 'V2',
527
- });
528
-
529
- expect(probeProtocolV2).toHaveBeenCalledTimes(1);
530
- expect(writeCharacteristic.writeWithResponse).not.toHaveBeenCalled();
531
- expect(writeCharacteristic.writeWithoutResponse).not.toHaveBeenCalled();
532
- await transport.release(uuid, true);
533
- });
534
-
535
427
  test.each(['ios', 'android'] as const)(
536
428
  'keeps a first expected Protocol V2 probe miss retryable on %s',
537
429
  async platform => {
@@ -567,37 +459,8 @@ describe('ReactNativeBleTransport Protocol V2 link lifecycle', () => {
567
459
  }
568
460
  );
569
461
 
570
- test.each([
571
- [
572
- 'Encryption is insufficient',
573
- { reason: 'Encryption is insufficient', attErrorCode: 15 },
574
- HardwareErrorCode.BleDeviceBondError,
575
- ],
576
- [
577
- 'Peer removed pairing information',
578
- { reason: 'Peer removed pairing information', iosErrorCode: 14 },
579
- HardwareErrorCode.BlePeerRemovedPairingInformation,
580
- ],
581
- ] as const)(
582
- 'fails Protocol V2 acquire immediately on %s instead of waiting for Ping',
583
- async (_label, nativeError, errorCode) => {
584
- const { transport, uuid, device } = createHarness({
585
- monitorError: Object.assign(new Error(nativeError.reason), nativeError),
586
- });
587
- const probe = jest.spyOn(transport as any, 'probeProtocolV2');
588
-
589
- await expect(transport.acquire({ uuid, expectedProtocol: 'V2' })).rejects.toMatchObject({
590
- errorCode,
591
- });
592
-
593
- expect(probe).not.toHaveBeenCalled();
594
- expect(device.cancelConnection).toHaveBeenCalled();
595
- expect(transport.getProtocolType(uuid)).toBeUndefined();
596
- }
597
- );
598
-
599
462
  test.each(['ios', 'android'] as const)(
600
- 'keeps a confirmed Protocol V2 probe miss retryable on %s without native bond evidence',
463
+ 'reports a stale bond on %s when a previously confirmed Protocol V2 device stops responding',
601
464
  async platform => {
602
465
  setPlatformOS(platform);
603
466
  const { transport, uuid, device } = createHarness();
@@ -606,10 +469,10 @@ describe('ReactNativeBleTransport Protocol V2 link lifecycle', () => {
606
469
  jest.spyOn(transport as any, 'probeProtocolV2').mockResolvedValue(false);
607
470
 
608
471
  await expect(transport.acquire({ uuid, expectedProtocol: 'V2' })).rejects.toMatchObject({
609
- errorCode: HardwareErrorCode.RuntimeError,
472
+ errorCode: HardwareErrorCode.BleDeviceBondError,
610
473
  });
611
474
 
612
- expect(device.cancelConnection).not.toHaveBeenCalled();
475
+ expect(device.cancelConnection).toHaveBeenCalled();
613
476
  expect(transport.getProtocolType(uuid)).toBeUndefined();
614
477
  }
615
478
  );
package/src/index.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { PermissionsAndroid, Platform } from 'react-native';
2
2
  import { Buffer } from 'buffer';
3
3
  import {
4
+ BleATTErrorCode,
4
5
  BleError,
5
6
  BleErrorCode,
6
7
  BleManager as BlePlxManager,
@@ -47,11 +48,6 @@ import {
47
48
  getInfosForServiceUuid,
48
49
  isSameBleUuid,
49
50
  } from './constants';
50
- import {
51
- isBleStaleBondHardwareError,
52
- isNativeBleStaleBondError,
53
- toBleStaleBondHardwareError,
54
- } from './bleStaleBond';
55
51
  import { isHeaderChunk } from './utils/validateNotify';
56
52
  import BleTransport from './BleTransport';
57
53
  import timer from './utils/timer';
@@ -62,15 +58,6 @@ import type { Characteristic, Device, Subscription } from 'react-native-ble-plx'
62
58
  import type EventEmitter from 'events';
63
59
  import type { BleAcquireInput, TransportOptions } from './types';
64
60
 
65
- type FirmwareInstallBleAcquireInput = BleAcquireInput & {
66
- /**
67
- * Reuse the already-verified protocol after an expected firmware-install
68
- * disconnect. The install loader accepts status requests but may not answer
69
- * the generic protocol probe used by a normal acquire.
70
- */
71
- skipProtocolProbe?: boolean;
72
- };
73
-
74
61
  const { check, ProtocolV1, parseConfigure } = transport;
75
62
 
76
63
  const Log = bleLogger;
@@ -320,10 +307,15 @@ const resolveNegotiatedMtu = (device: Device) => requestNegotiatedMtu(device, 'c
320
307
 
321
308
  type IOBleErrorRemap = Error | BleError | null | undefined;
322
309
 
323
- function remapError(error: IOBleErrorRemap, mapProtocolV2StaleBond: boolean) {
310
+ function remapError(error: IOBleErrorRemap) {
324
311
  if (error instanceof BleError) {
325
- if (mapProtocolV2StaleBond && isNativeBleStaleBondError(error)) {
326
- throw toBleStaleBondHardwareError(error);
312
+ if (
313
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
314
+ // @ts-expect-error
315
+ error.iosErrorCode === BleATTErrorCode.UnlikelyError ||
316
+ error.reason === 'Peer removed pairing information'
317
+ ) {
318
+ throw ERRORS.TypedError(HardwareErrorCode.BlePeerRemovedPairingInformation);
327
319
  }
328
320
 
329
321
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
@@ -398,16 +390,6 @@ export default class ReactNativeBleTransport {
398
390
  /** Consecutive detections that failed while trusting sessionProtocols. */
399
391
  private protocolReprobeFailures: Map<string, number> = new Map();
400
392
 
401
- /**
402
- * Native encryption/pairing failures seen before Protocol V2 probe starts.
403
- * Pro2/Neo GATT connect can succeed on a stale iOS bond; the CCCD write then
404
- * fails with ATT 5/15. Remember it so detectProtocol fails immediately.
405
- */
406
- private staleBondErrors: Map<string, Error> = new Map();
407
-
408
- /** Strict or previously confirmed V2 target while acquire installs notifications. */
409
- private acquiringProtocolV2 = new Set<string>();
410
-
411
393
  private protocolV2Assemblers: Map<string, ProtocolV2FrameAssembler> = new Map();
412
394
 
413
395
  private protocolV2FrameQueues: Map<string, Uint8Array[]> = new Map();
@@ -883,7 +865,7 @@ export default class ReactNativeBleTransport {
883
865
  return transport;
884
866
  }
885
867
 
886
- async acquire(input: FirmwareInstallBleAcquireInput) {
868
+ async acquire(input: BleAcquireInput) {
887
869
  const { uuid } = input;
888
870
 
889
871
  if (!uuid) {
@@ -893,73 +875,28 @@ export default class ReactNativeBleTransport {
893
875
  return this.runLifecycleOperation(uuid, () => this.acquireUnlocked(input));
894
876
  }
895
877
 
896
- private async acquireUnlocked(input: FirmwareInstallBleAcquireInput) {
897
- const { uuid, forceCleanRunPromise, expectedProtocol, skipProtocolProbe } = input;
898
- const shouldMapProtocolV2StaleBond = expectedProtocol
899
- ? expectedProtocol === 'V2'
900
- : this.confirmedProtocolV2.has(uuid);
878
+ private async acquireUnlocked(input: BleAcquireInput) {
879
+ const { uuid, forceCleanRunPromise, expectedProtocol } = input;
901
880
 
902
881
  const cachedTransport = transportCache[uuid];
903
- if (skipProtocolProbe && !cachedTransport && this.blePlxManager) {
904
- Log?.debug(
905
- '[ReactNativeBleTransport] refresh uncached BLE connection for firmware install:',
906
- uuid
907
- );
908
- const manager = this.blePlxManager;
909
- await this.runNativeTeardown(uuid, manager, async () => {
910
- await this.runBestEffortNativeOperation(
911
- 'firmware install reconnect: cancel uncached device connection',
912
- () => manager.cancelDeviceConnection(uuid)
913
- );
914
- });
915
- }
916
882
  if (cachedTransport) {
917
- if (skipProtocolProbe) {
918
- Log?.debug(
919
- '[ReactNativeBleTransport] refresh cached BLE connection for firmware install:',
920
- uuid
921
- );
922
- const manager = this.blePlxManager;
923
- await this.releaseUnlocked(uuid, true);
924
- await this.runNativeTeardown(uuid, manager, async () => {
925
- const operations: Promise<unknown>[] = [];
926
- if (manager) {
927
- operations.push(
928
- this.runBestEffortNativeOperation(
929
- 'firmware install reconnect: cancel device connection',
930
- () => manager.cancelDeviceConnection(uuid)
931
- )
932
- );
933
- }
934
- operations.push(
935
- this.runBestEffortNativeOperation(
936
- 'firmware install reconnect: device cancel connection',
937
- () => cachedTransport.device.cancelConnection()
938
- )
939
- );
940
- await Promise.all(operations);
941
- });
942
- } else {
943
- const cachedProtocol = this.deviceProtocol.get(uuid);
944
- const isCachedDeviceConnected = await cachedTransport.device
945
- .isConnected()
946
- .catch(() => false);
947
- if (
948
- isCachedDeviceConnected &&
949
- cachedProtocol &&
950
- (!expectedProtocol || cachedProtocol === expectedProtocol)
951
- ) {
952
- Log?.debug('[ReactNativeBleTransport] reuse cached BLE transport:', uuid, cachedProtocol);
953
- return { uuid, protocolType: cachedProtocol };
954
- }
955
-
956
- /**
957
- * If the transport is not reusable due to a protocol mismatch or stale
958
- * connection, clean it up before creating a new transport instance.
959
- */
960
- Log?.debug('transport not reusable, will release: ', uuid);
961
- await this.releaseUnlocked(uuid, true);
883
+ const cachedProtocol = this.deviceProtocol.get(uuid);
884
+ const isCachedDeviceConnected = await cachedTransport.device.isConnected().catch(() => false);
885
+ if (
886
+ isCachedDeviceConnected &&
887
+ cachedProtocol &&
888
+ (!expectedProtocol || cachedProtocol === expectedProtocol)
889
+ ) {
890
+ Log?.debug('[ReactNativeBleTransport] reuse cached BLE transport:', uuid, cachedProtocol);
891
+ return { uuid, protocolType: cachedProtocol };
962
892
  }
893
+
894
+ /**
895
+ * If the transport is not reusable due to a protocol mismatch or stale
896
+ * connection, clean it up before creating a new transport instance.
897
+ */
898
+ Log?.debug('transport not reusable, will release: ', uuid);
899
+ await this.releaseUnlocked(uuid, true);
963
900
  }
964
901
 
965
902
  let device: Device | null = null;
@@ -1024,7 +961,7 @@ export default class ReactNativeBleTransport {
1024
961
  Log?.debug('device already connected');
1025
962
  throw ERRORS.TypedError(HardwareErrorCode.BleAlreadyConnected);
1026
963
  } else {
1027
- remapError(e, shouldMapProtocolV2StaleBond);
964
+ remapError(e);
1028
965
  }
1029
966
  }
1030
967
  }
@@ -1068,7 +1005,7 @@ export default class ReactNativeBleTransport {
1068
1005
  }
1069
1006
  }
1070
1007
  } else {
1071
- remapError(e, shouldMapProtocolV2StaleBond);
1008
+ remapError(e);
1072
1009
  }
1073
1010
  }
1074
1011
  }
@@ -1088,48 +1025,12 @@ export default class ReactNativeBleTransport {
1088
1025
  this.deviceProtocolHints.set(uuid, protocolHint);
1089
1026
  }
1090
1027
 
1091
- if (shouldMapProtocolV2StaleBond) {
1092
- this.acquiringProtocolV2.add(uuid);
1093
- }
1028
+ await this.installTransportForAcquire(uuid, acquiredDevice, {
1029
+ writeCharacteristic,
1030
+ notifyCharacteristic,
1031
+ });
1094
1032
 
1095
1033
  try {
1096
- await this.installTransportForAcquire(uuid, acquiredDevice, {
1097
- writeCharacteristic,
1098
- notifyCharacteristic,
1099
- });
1100
-
1101
- if (skipProtocolProbe) {
1102
- if (!expectedProtocol) {
1103
- throw ERRORS.TypedError(
1104
- HardwareErrorCode.RuntimeError,
1105
- 'skipProtocolProbe requires an expected BLE protocol'
1106
- );
1107
- }
1108
- const hasConfirmedProtocol =
1109
- this.sessionProtocols.get(uuid) === expectedProtocol ||
1110
- (expectedProtocol === 'V2' && this.confirmedProtocolV2.has(uuid));
1111
- if (!hasConfirmedProtocol) {
1112
- throw ERRORS.TypedError(
1113
- HardwareErrorCode.RuntimeError,
1114
- 'skipProtocolProbe requires a previously confirmed protocol for this BLE endpoint'
1115
- );
1116
- }
1117
- this.deviceProtocol.set(uuid, expectedProtocol);
1118
- this.sessionProtocols.set(uuid, expectedProtocol);
1119
- this.protocolReprobeFailures.delete(uuid);
1120
- Log?.debug('[ReactNativeBleTransport] protocol selected without probe', {
1121
- deviceId: uuid,
1122
- protocol: expectedProtocol,
1123
- source: 'firmware-install-reconnect',
1124
- });
1125
- const currentTransport = transportCache[uuid];
1126
- if (!currentTransport) {
1127
- throw ERRORS.TypedError(HardwareErrorCode.TransportNotFound);
1128
- }
1129
- this.attachDisconnectSubscription(currentTransport, currentTransport.device, uuid);
1130
- return { uuid, protocolType: expectedProtocol };
1131
- }
1132
-
1133
1034
  const protocolType = await this.detectProtocol(
1134
1035
  uuid,
1135
1036
  expectedProtocol,
@@ -1145,14 +1046,12 @@ export default class ReactNativeBleTransport {
1145
1046
  this.attachDisconnectSubscription(currentTransport, currentTransport.device, uuid);
1146
1047
  return { uuid, protocolType };
1147
1048
  } catch (error) {
1148
- if (isBleStaleBondHardwareError(error)) {
1049
+ if ((error as { errorCode?: unknown })?.errorCode === HardwareErrorCode.BleDeviceBondError) {
1149
1050
  await this.disconnectUnlocked(uuid);
1150
1051
  } else {
1151
1052
  await this.releaseUnlocked(uuid, true);
1152
1053
  }
1153
1054
  throw error;
1154
- } finally {
1155
- this.acquiringProtocolV2.delete(uuid);
1156
1055
  }
1157
1056
  }
1158
1057
 
@@ -1180,21 +1079,17 @@ export default class ReactNativeBleTransport {
1180
1079
  Log?.debug('monitor error ignored for stale transport: ', uuid, notifyTransactionId);
1181
1080
  return;
1182
1081
  }
1183
- if (
1184
- (this.getActiveProtocol(uuid) === 'V2' || this.acquiringProtocolV2.has(uuid)) &&
1185
- isNativeBleStaleBondError(error)
1186
- ) {
1187
- this.rememberStaleBondError(uuid, toBleStaleBondHardwareError(error));
1188
- return;
1189
- }
1190
1082
  if (this.getActiveProtocol(uuid) === 'V2') {
1191
1083
  let errorCode:
1084
+ | typeof HardwareErrorCode.BleDeviceBondError
1192
1085
  | typeof HardwareErrorCode.BleCharacteristicNotifyError
1193
1086
  | typeof HardwareErrorCode.BleCharacteristicNotifyChangeFailure
1194
1087
  | typeof HardwareErrorCode.BleTimeoutError =
1195
1088
  HardwareErrorCode.BleCharacteristicNotifyError;
1196
1089
  if (error.reason?.includes('The connection has timed out unexpectedly')) {
1197
1090
  errorCode = HardwareErrorCode.BleTimeoutError;
1091
+ } else if (error.reason?.includes('Encryption is insufficient')) {
1092
+ errorCode = HardwareErrorCode.BleDeviceBondError;
1198
1093
  } else if (
1199
1094
  error.reason?.includes('Cannot write client characteristic config descriptor') ||
1200
1095
  error.reason?.includes('Cannot find client characteristic config descriptor') ||
@@ -1209,12 +1104,16 @@ export default class ReactNativeBleTransport {
1209
1104
  }
1210
1105
  if (this.runPromise && this.runPromiseDeviceId === uuid) {
1211
1106
  let ERROR:
1107
+ | typeof HardwareErrorCode.BleDeviceBondError
1212
1108
  | typeof HardwareErrorCode.BleCharacteristicNotifyError
1213
1109
  | typeof HardwareErrorCode.BleTimeoutError =
1214
1110
  HardwareErrorCode.BleCharacteristicNotifyError;
1215
1111
  if (error.reason?.includes('The connection has timed out unexpectedly')) {
1216
1112
  ERROR = HardwareErrorCode.BleTimeoutError;
1217
1113
  }
1114
+ if (error.reason?.includes('Encryption is insufficient')) {
1115
+ ERROR = HardwareErrorCode.BleDeviceBondError;
1116
+ }
1218
1117
  if (
1219
1118
  error.reason?.includes('Cannot write client characteristic config descriptor') ||
1220
1119
  error.reason?.includes('Cannot find client characteristic config descriptor') || // pro firmware 2.3.0 upgrade
@@ -1349,8 +1248,6 @@ export default class ReactNativeBleTransport {
1349
1248
 
1350
1249
  this.deviceProtocol.delete(uuid);
1351
1250
  this.probingProtocols.delete(uuid);
1352
- this.staleBondErrors.delete(uuid);
1353
- this.acquiringProtocolV2.delete(uuid);
1354
1251
  // Confirmed protocol and caller hints stay in deviceProtocol / protocolHint.
1355
1252
  this.protocolV2Assemblers.get(uuid)?.reset();
1356
1253
  this.protocolV2Assemblers.delete(uuid);
@@ -1723,7 +1620,6 @@ export default class ReactNativeBleTransport {
1723
1620
  }
1724
1621
  this.deviceProtocol.delete(session);
1725
1622
  this.probingProtocols.delete(session);
1726
- this.staleBondErrors.delete(session);
1727
1623
  this.deviceProtocolHints.delete(session);
1728
1624
  this.sessionProtocols.delete(session);
1729
1625
  this.protocolReprobeFailures.delete(session);
@@ -1947,8 +1843,6 @@ export default class ReactNativeBleTransport {
1947
1843
  }
1948
1844
  this.deviceProtocol.delete(uuid);
1949
1845
  this.probingProtocols.delete(uuid);
1950
- this.staleBondErrors.delete(uuid);
1951
- this.acquiringProtocolV2.delete(uuid);
1952
1846
  this.protocolV2Assemblers.delete(uuid);
1953
1847
  this.resetProtocolV2Frames(uuid);
1954
1848
 
@@ -2045,8 +1939,6 @@ export default class ReactNativeBleTransport {
2045
1939
  }
2046
1940
  this.deviceProtocol.delete(uuid);
2047
1941
  this.probingProtocols.delete(uuid);
2048
- this.staleBondErrors.delete(uuid);
2049
- this.acquiringProtocolV2.delete(uuid);
2050
1942
  this.protocolV2Assemblers.delete(uuid);
2051
1943
  this.resetProtocolV2Frames(uuid);
2052
1944
 
@@ -2097,11 +1989,8 @@ export default class ReactNativeBleTransport {
2097
1989
  });
2098
1990
  this.deviceProtocol.clear();
2099
1991
  this.probingProtocols.clear();
2100
- this.staleBondErrors.clear();
2101
- this.acquiringProtocolV2.clear();
2102
1992
  this.sessionProtocols.clear();
2103
- // Keep transport-lifetime V2 proof so the same endpoint can finish a no-probe
2104
- // firmware reconnect after the native BLE manager is recreated.
1993
+ this.confirmedProtocolV2.clear();
2105
1994
  this.protocolReprobeFailures.clear();
2106
1995
  this.writeTimeoutCounts.clear();
2107
1996
  this.connectionSetupTimeoutCounts.clear();
@@ -2114,11 +2003,12 @@ export default class ReactNativeBleTransport {
2114
2003
  }
2115
2004
  }
2116
2005
 
2117
- private createProtocolMismatchError(expected: ProtocolType) {
2118
- // A protocol probe miss alone does not prove that the OS bond is stale.
2119
- // Native authentication/encryption failures are mapped separately.
2006
+ private createProtocolMismatchError(expected: ProtocolType, uuid: string) {
2007
+ // A generic Ping miss is not a bond failure. Only a later miss after this
2008
+ // endpoint already answered V2, or a native encryption/pairing error, is.
2009
+ const isStaleV2Bond = expected === 'V2' && this.confirmedProtocolV2.has(uuid);
2120
2010
  return ERRORS.TypedError(
2121
- HardwareErrorCode.RuntimeError,
2011
+ isStaleV2Bond ? HardwareErrorCode.BleDeviceBondError : HardwareErrorCode.RuntimeError,
2122
2012
  `Device protocol mismatch: expected ${expected}, but device did not respond to expected protocol`
2123
2013
  );
2124
2014
  }
@@ -2150,28 +2040,31 @@ export default class ReactNativeBleTransport {
2150
2040
  protocolHint?: ProtocolType,
2151
2041
  rebuildTransport?: () => Promise<void>
2152
2042
  ): Promise<ProtocolType> {
2153
- // A declared V1 is taken at face value on every platform, as iOS has done
2154
- // since protocol probing arrived: the caller reads the protocol off its own
2155
- // device record, so the probe re-asks a question that is already answered
2156
- // and costs a round trip on every acquire. Expected V2 must still Ping so
2157
- // USB-priority `link disabled` surfaces here instead of as a later unmapped
2158
- // RuntimeError. sessionProtocols is deliberately NOT stamped here: that map
2159
- // records protocols the device actually answered on (it gates the
2160
- // trustSessionProtocol narrowing in forced detection), and this branch has
2161
- // received no response. skipProtocolProbe does not need it either — its only
2162
- // caller is the V2 firmware-install reconnect.
2163
- if (expectedProtocol === 'V1') {
2164
- this.deviceProtocol.set(uuid, 'V1');
2043
+ // iOS still skips an extra V1 Initialize during acquire. Expected V2 must
2044
+ // Ping so USB-priority `link disabled` can surface instead of a later
2045
+ // unmapped RuntimeError.
2046
+ if (Platform.OS === 'ios' && expectedProtocol === 'V1') {
2047
+ this.deviceProtocol.set(uuid, expectedProtocol);
2165
2048
  Log?.debug('[ReactNativeBleTransport] protocol selected', {
2166
2049
  deviceId: uuid,
2167
- protocol: 'V1',
2050
+ protocol: expectedProtocol,
2168
2051
  source: 'expected',
2169
2052
  });
2170
- return 'V1';
2053
+ return expectedProtocol;
2171
2054
  }
2172
2055
 
2173
- if (expectedProtocol === 'V2' || this.acquiringProtocolV2.has(uuid)) {
2174
- this.throwIfStaleBondError(uuid);
2056
+ if (expectedProtocol === 'V1') {
2057
+ if (await this.probeProtocolV1(uuid)) {
2058
+ this.deviceProtocol.set(uuid, 'V1');
2059
+ this.sessionProtocols.set(uuid, 'V1');
2060
+ Log?.debug('[ReactNativeBleTransport] protocol detected', {
2061
+ deviceId: uuid,
2062
+ protocol: 'V1',
2063
+ source: 'expected',
2064
+ });
2065
+ return 'V1';
2066
+ }
2067
+ throw this.createProtocolMismatchError(expectedProtocol, uuid);
2175
2068
  }
2176
2069
 
2177
2070
  if (expectedProtocol === 'V2') {
@@ -2186,7 +2079,7 @@ export default class ReactNativeBleTransport {
2186
2079
  });
2187
2080
  return 'V2';
2188
2081
  }
2189
- throw this.createProtocolMismatchError(expectedProtocol);
2082
+ throw this.createProtocolMismatchError(expectedProtocol, uuid);
2190
2083
  }
2191
2084
 
2192
2085
  // Protocol must be actively probed after connection. Name, PID, and descriptors only
@@ -2330,7 +2223,6 @@ export default class ReactNativeBleTransport {
2330
2223
 
2331
2224
  this.probingProtocols.set(uuid, 'V2');
2332
2225
  this.protocolV2Assemblers.get(uuid)?.reset();
2333
- this.throwIfStaleBondError(uuid);
2334
2226
  const detected = await probeProtocolV2Helper({
2335
2227
  call: (name: string, data: Record<string, unknown>, options?: TransportCallOptions) =>
2336
2228
  this.callProtocolV2(uuid, name, data, options),
@@ -2341,7 +2233,6 @@ export default class ReactNativeBleTransport {
2341
2233
  this.protocolV2Assemblers.get(uuid)?.reset();
2342
2234
  this.resetProtocolV2Frames(uuid);
2343
2235
  },
2344
- shouldRethrow: isBleStaleBondHardwareError,
2345
2236
  });
2346
2237
  if (!detected) {
2347
2238
  this.clearProbeProtocol(uuid, 'V2');
@@ -2410,21 +2301,6 @@ export default class ReactNativeBleTransport {
2410
2301
  }
2411
2302
  }
2412
2303
 
2413
- private rememberStaleBondError(uuid: string, error: Error) {
2414
- this.staleBondErrors.set(uuid, error);
2415
- this.rejectProtocolV2Frames(uuid, error);
2416
- if (this.runPromise && this.runPromiseDeviceId === uuid) {
2417
- this.runPromise.reject(error);
2418
- }
2419
- }
2420
-
2421
- private throwIfStaleBondError(uuid: string) {
2422
- const error = this.staleBondErrors.get(uuid);
2423
- if (error) {
2424
- throw error;
2425
- }
2426
- }
2427
-
2428
2304
  private async readProtocolV2Frame(uuid: string) {
2429
2305
  const queuedFrame = this.getProtocolV2FrameQueue(uuid).shift();
2430
2306
  if (queuedFrame) {
@@ -2483,11 +2359,6 @@ export default class ReactNativeBleTransport {
2483
2359
  assertCurrentGeneration();
2484
2360
  return;
2485
2361
  } catch (error) {
2486
- if (isNativeBleStaleBondError(error) || isBleStaleBondHardwareError(error)) {
2487
- const bondError = toBleStaleBondHardwareError(error);
2488
- this.rememberStaleBondError(uuid, bondError);
2489
- throw bondError;
2490
- }
2491
2362
  if (
2492
2363
  getFirmwareUploadWriteRetryType(error) !== 'congested' ||
2493
2364
  attempt >= FIRMWARE_UPLOAD_WRITE_MAX_RETRIES
@@ -1,5 +0,0 @@
1
- import { isBleStaleBondHardwareError } from '@onekeyfe/hd-shared';
2
- export { isBleStaleBondHardwareError };
3
- export declare const isNativeBleStaleBondError: (error: unknown) => boolean;
4
- export declare const toBleStaleBondHardwareError: (error: unknown) => Error;
5
- //# sourceMappingURL=bleStaleBond.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"bleStaleBond.d.ts","sourceRoot":"","sources":["../src/bleStaleBond.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,2BAA2B,EAC5B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,2BAA2B,EAAE,CAAC;AAkBvC,eAAO,MAAM,yBAAyB,UAAW,OAAO,KAAG,OAe1D,CAAC;AAEF,eAAO,MAAM,2BAA2B,UAAW,OAAO,UAkBzD,CAAC"}
@@ -1,39 +0,0 @@
1
- import { HardwareErrorCode } from '@onekeyfe/hd-shared';
2
-
3
- import { isNativeBleStaleBondError, toBleStaleBondHardwareError } from '../bleStaleBond';
4
-
5
- describe('native BLE stale bond mapping', () => {
6
- test.each([
7
- [
8
- { attErrorCode: 15, reason: 'Encryption is insufficient' },
9
- HardwareErrorCode.BleDeviceBondError,
10
- ],
11
- [
12
- { attErrorCode: 5, reason: 'GATT_INSUF_AUTHENTICATION' },
13
- HardwareErrorCode.BleDeviceBondError,
14
- ],
15
- [
16
- { iosErrorCode: 14, reason: 'Peer removed pairing information' },
17
- HardwareErrorCode.BlePeerRemovedPairingInformation,
18
- ],
19
- [
20
- { reason: 'peer removed pairing information' },
21
- HardwareErrorCode.BlePeerRemovedPairingInformation,
22
- ],
23
- [
24
- { message: 'PEER REMOVED PAIRING INFORMATION' },
25
- HardwareErrorCode.BlePeerRemovedPairingInformation,
26
- ],
27
- ])('maps %j to %s', (nativeError, errorCode) => {
28
- expect(isNativeBleStaleBondError(nativeError)).toBe(true);
29
- expect(toBleStaleBondHardwareError(nativeError)).toMatchObject({ errorCode });
30
- });
31
-
32
- test('does not treat the generic ATT unlikely error as a stale bond', () => {
33
- expect(isNativeBleStaleBondError({ attErrorCode: 14, reason: 'Unlikely error' })).toBe(false);
34
- });
35
-
36
- test('does not treat a generic disconnect as a stale bond', () => {
37
- expect(isNativeBleStaleBondError({ reason: 'Device disconnected' })).toBe(false);
38
- });
39
- });
@@ -1,61 +0,0 @@
1
- import {
2
- ERRORS,
3
- HardwareErrorCode,
4
- isBleStaleBondErrorText,
5
- isBleStaleBondHardwareError,
6
- } from '@onekeyfe/hd-shared';
7
-
8
- export { isBleStaleBondHardwareError };
9
-
10
- const ATT_INSUFFICIENT_AUTHENTICATION = 5;
11
- const ATT_INSUFFICIENT_ENCRYPTION = 15;
12
- const IOS_PEER_REMOVED_PAIRING_INFORMATION = 14;
13
-
14
- type NativeBleErrorFields = {
15
- attErrorCode?: unknown;
16
- iosErrorCode?: unknown;
17
- reason?: unknown;
18
- message?: unknown;
19
- };
20
-
21
- const nativeErrorText = (error: NativeBleErrorFields) =>
22
- [error.reason, error.message]
23
- .filter((value): value is string => typeof value === 'string')
24
- .join(' ');
25
-
26
- export const isNativeBleStaleBondError = (error: unknown): boolean => {
27
- if (!error || typeof error !== 'object') {
28
- return typeof error === 'string' ? isBleStaleBondErrorText(error) : false;
29
- }
30
-
31
- const nativeError = error as NativeBleErrorFields;
32
- if (
33
- nativeError.attErrorCode === ATT_INSUFFICIENT_AUTHENTICATION ||
34
- nativeError.attErrorCode === ATT_INSUFFICIENT_ENCRYPTION ||
35
- nativeError.iosErrorCode === IOS_PEER_REMOVED_PAIRING_INFORMATION
36
- ) {
37
- return true;
38
- }
39
-
40
- return isBleStaleBondErrorText(nativeErrorText(nativeError));
41
- };
42
-
43
- export const toBleStaleBondHardwareError = (error: unknown) => {
44
- if (isBleStaleBondHardwareError(error)) {
45
- return error as Error;
46
- }
47
-
48
- const nativeError = (error ?? {}) as NativeBleErrorFields;
49
- const text = nativeErrorText(nativeError);
50
- const normalizedText = text.toLowerCase();
51
- const peerRemoved =
52
- nativeError.iosErrorCode === IOS_PEER_REMOVED_PAIRING_INFORMATION ||
53
- normalizedText.includes('peer removed pairing information');
54
-
55
- return ERRORS.TypedError(
56
- peerRemoved
57
- ? HardwareErrorCode.BlePeerRemovedPairingInformation
58
- : HardwareErrorCode.BleDeviceBondError,
59
- text || undefined
60
- );
61
- };