@onekeyfe/hd-transport-react-native 1.2.0-alpha.2 → 1.2.0-alpha.21

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.js CHANGED
@@ -138,21 +138,6 @@ const isSameBleUuid = (left, right) => {
138
138
  function hasWritableCapability(characteristic) {
139
139
  return !!(characteristic.isWritableWithResponse || characteristic.isWritableWithoutResponse);
140
140
  }
141
- function resolveBleWriteMode(characteristic, preferredMode = 'withoutResponse') {
142
- if (preferredMode === 'withoutResponse' && characteristic.isWritableWithoutResponse) {
143
- return 'withoutResponse';
144
- }
145
- if (preferredMode === 'withResponse' && characteristic.isWritableWithResponse) {
146
- return 'withResponse';
147
- }
148
- if (characteristic.isWritableWithoutResponse) {
149
- return 'withoutResponse';
150
- }
151
- if (characteristic.isWritableWithResponse) {
152
- return 'withResponse';
153
- }
154
- return preferredMode;
155
- }
156
141
  function resolveProtocolV2PacketCapacity({ platform, iosPacketLength = IOS_PACKET_LENGTH, androidPacketLength = ANDROID_PACKET_LENGTH, mtu, }) {
157
142
  if (platform === 'ios') {
158
143
  return iosPacketLength;
@@ -189,7 +174,6 @@ const timer = process.env.NODE_ENV === 'development'
189
174
  const subscribeBleOn = (bleManager, ms = 1000) => new Promise((resolve, reject) => {
190
175
  let done = false;
191
176
  const subscription = bleManager.onStateChange(state => {
192
- console.log('ble state -> ', state);
193
177
  if (state === 'PoweredOn') {
194
178
  if (done)
195
179
  return;
@@ -261,6 +245,18 @@ class BleTransport {
261
245
  BleTransport.MAX_RETRIES = 5;
262
246
  BleTransport.RETRY_DELAY = 2000;
263
247
 
248
+ function createTransportCallLog(name, protocol, data) {
249
+ if (name === 'ResourceUpdate' || name === 'ResourceAck') {
250
+ return {
251
+ name,
252
+ protocol,
253
+ file_name: data.file_name,
254
+ hash: data.hash,
255
+ };
256
+ }
257
+ return { name, protocol };
258
+ }
259
+
264
260
  const { check, ProtocolV1, parseConfigure } = transport__default["default"];
265
261
  const Log = bleLogger;
266
262
  const transportCache = {};
@@ -299,16 +295,9 @@ const PROTOCOL_V2_PROBE_TIMEOUT_MS = 10000;
299
295
  const DEVICE_SCAN_TIMEOUT_MS = 8000;
300
296
  const IOS_NOTIFY_READY_DELAY_MS = 150;
301
297
  const ANDROID_NOTIFY_READY_DELAY_MS = 300;
302
- const HIGH_VOLUME_WRITE_BURST_SIZE = reactNative.Platform.OS === 'ios' ? 4 : 6;
303
- const HIGH_VOLUME_WRITE_PAUSE_MS = reactNative.Platform.OS === 'ios' ? 6 : 2;
304
- const HIGH_VOLUME_WRITE_FLUSH_DELAY_MS = reactNative.Platform.OS === 'ios' ? 20 : 8;
305
298
  const DEFAULT_PROTOCOL_V2_BLE_TUNING = {
306
299
  iosPacketLength: IOS_PACKET_LENGTH,
307
300
  androidPacketLength: ANDROID_PACKET_LENGTH,
308
- highVolumeWriteBurstSize: HIGH_VOLUME_WRITE_BURST_SIZE,
309
- highVolumeWritePauseMs: HIGH_VOLUME_WRITE_PAUSE_MS,
310
- highVolumeWriteFlushDelayMs: HIGH_VOLUME_WRITE_FLUSH_DELAY_MS,
311
- highVolumeWriteWithResponse: false,
312
301
  };
313
302
  let protocolV2BleTuning = Object.assign({}, DEFAULT_PROTOCOL_V2_BLE_TUNING);
314
303
  const normalizePositiveInteger = (value, fallback) => {
@@ -318,20 +307,15 @@ const normalizePositiveInteger = (value, fallback) => {
318
307
  return Math.floor(normalized);
319
308
  };
320
309
  function configureProtocolV2BleTuning(tuning = {}) {
321
- var _a;
322
310
  protocolV2BleTuning = {
323
311
  iosPacketLength: normalizePositiveInteger(tuning.iosPacketLength, protocolV2BleTuning.iosPacketLength),
324
312
  androidPacketLength: normalizePositiveInteger(tuning.androidPacketLength, protocolV2BleTuning.androidPacketLength),
325
- highVolumeWriteBurstSize: normalizePositiveInteger(tuning.highVolumeWriteBurstSize, protocolV2BleTuning.highVolumeWriteBurstSize),
326
- highVolumeWritePauseMs: normalizePositiveInteger(tuning.highVolumeWritePauseMs, protocolV2BleTuning.highVolumeWritePauseMs),
327
- highVolumeWriteFlushDelayMs: normalizePositiveInteger(tuning.highVolumeWriteFlushDelayMs, protocolV2BleTuning.highVolumeWriteFlushDelayMs),
328
- highVolumeWriteWithResponse: (_a = tuning.highVolumeWriteWithResponse) !== null && _a !== void 0 ? _a : protocolV2BleTuning.highVolumeWriteWithResponse,
329
313
  };
330
- Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V2 BLE tuning configured:', protocolV2BleTuning);
314
+ Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] BLE tuning configured', protocolV2BleTuning);
331
315
  }
332
316
  function resetProtocolV2BleTuning() {
333
317
  protocolV2BleTuning = Object.assign({}, DEFAULT_PROTOCOL_V2_BLE_TUNING);
334
- Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V2 BLE tuning reset:', protocolV2BleTuning);
318
+ Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] BLE tuning reset', protocolV2BleTuning);
335
319
  }
336
320
  function getProtocolV2BleTuning() {
337
321
  return Object.assign({}, protocolV2BleTuning);
@@ -371,9 +355,10 @@ const requestAndroidMtu = (device) => __awaiter(void 0, void 0, void 0, function
371
355
  return device;
372
356
  try {
373
357
  const mtuDevice = yield device.requestMTU(ANDROID_REQUEST_MTU);
374
- Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Android MTU requested:', {
358
+ Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] MTU configured', {
359
+ deviceId: device.id,
375
360
  requested: ANDROID_REQUEST_MTU,
376
- mtu: mtuDevice.mtu,
361
+ actual: mtuDevice.mtu,
377
362
  });
378
363
  return mtuDevice;
379
364
  }
@@ -414,8 +399,27 @@ class ReactNativeBleTransport {
414
399
  this.protocolV2Assemblers = new Map();
415
400
  this.protocolV2FrameQueues = new Map();
416
401
  this.protocolV2FramePromises = new Map();
417
- this.activeProtocolV2Call = null;
418
- this.nextProtocolV2CallToken = 1;
402
+ this.protocolV2Links = new transport.ProtocolV2LinkManager({
403
+ getSchemas: () => {
404
+ if (!this._messages || !this._messagesV2) {
405
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.TransportNotConfigured);
406
+ }
407
+ return {
408
+ protocolV1: this._messages,
409
+ protocolV2: this._messagesV2,
410
+ };
411
+ },
412
+ classifyError: () => 'link-fatal',
413
+ onLinkInvalidated: (uuid, reason) => __awaiter(this, void 0, void 0, function* () {
414
+ var _b;
415
+ (_b = this.protocolV2Assemblers.get(uuid)) === null || _b === void 0 ? void 0 : _b.reset();
416
+ this.rejectProtocolV2Frames(uuid, new Error(reason));
417
+ Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V2 link invalidated:', uuid, reason);
418
+ if (reason.startsWith('Protocol V2 link-fatal error:')) {
419
+ yield this.release(uuid, true);
420
+ }
421
+ }),
422
+ });
419
423
  this.monitorTokens = new Map();
420
424
  this.nextMonitorToken = 1;
421
425
  this.scanTimeout = (_a = options.scanTimeout) !== null && _a !== void 0 ? _a : DEVICE_SCAN_TIMEOUT_MS;
@@ -431,7 +435,9 @@ class ReactNativeBleTransport {
431
435
  }
432
436
  configureProtocolV2(signedData) {
433
437
  this._messagesV2 = parseConfigure(signedData);
434
- Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V2 schema configured');
438
+ this.protocolV2Links
439
+ .invalidateAllLinks('Protocol V2 schema reconfigured')
440
+ .catch(error => Log === null || Log === void 0 ? void 0 : Log.debug('Protocol V2 schema link cleanup failed:', error));
435
441
  }
436
442
  listen() {
437
443
  }
@@ -624,13 +630,12 @@ class ReactNativeBleTransport {
624
630
  return;
625
631
  }
626
632
  }
627
- blePlxManager.startDeviceScan(null, {
633
+ blePlxManager.startDeviceScan(getBluetoothServiceUuids(), {
628
634
  allowDuplicates: true,
629
635
  scanMode: reactNativeBlePlx.ScanMode.LowLatency,
630
636
  }, (error, device) => {
631
637
  var _a, _b, _c;
632
638
  if (error) {
633
- Log === null || Log === void 0 ? void 0 : Log.debug('ble scan manager: ', blePlxManager);
634
639
  Log === null || Log === void 0 ? void 0 : Log.debug('ble scan error: ', error);
635
640
  if ([reactNativeBlePlx.BleErrorCode.BluetoothPoweredOff, reactNativeBlePlx.BleErrorCode.BluetoothInUnknownState].includes(error.errorCode)) {
636
641
  reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BlePermissionError));
@@ -653,22 +658,8 @@ class ReactNativeBleTransport {
653
658
  const isOneKey = hdShared.isOnekeyDevice((_b = device === null || device === void 0 ? void 0 : device.name) !== null && _b !== void 0 ? _b : null, device === null || device === void 0 ? void 0 : device.id) ||
654
659
  hdShared.isOnekeyDevice((_c = device === null || device === void 0 ? void 0 : device.localName) !== null && _c !== void 0 ? _c : null, device === null || device === void 0 ? void 0 : device.id) ||
655
660
  hasKnownOneKeyService(device);
656
- const shouldTraceCandidate = !!displayName && /onekey|bixinkey|pro\s*2|pro\b|touch|^k\d|^t\d/i.test(displayName);
657
- if (shouldTraceCandidate) {
658
- Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] scan candidate', {
659
- name: device === null || device === void 0 ? void 0 : device.name,
660
- localName: device === null || device === void 0 ? void 0 : device.localName,
661
- id: device === null || device === void 0 ? void 0 : device.id,
662
- serviceUUIDs: device === null || device === void 0 ? void 0 : device.serviceUUIDs,
663
- accepted: isOneKey,
664
- });
665
- }
666
661
  if (isOneKey) {
667
- Log === null || Log === void 0 ? void 0 : Log.debug('search device start ======================');
668
- const { name, localName, id, serviceUUIDs } = device !== null && device !== void 0 ? device : {};
669
- Log === null || Log === void 0 ? void 0 : Log.debug(`device name: ${name !== null && name !== void 0 ? name : ''}\nlocalName: ${localName !== null && localName !== void 0 ? localName : ''}\nid: ${id !== null && id !== void 0 ? id : ''}\nserviceUUIDs: ${(serviceUUIDs !== null && serviceUUIDs !== void 0 ? serviceUUIDs : []).join(',')}`);
670
662
  addDevice(device);
671
- Log === null || Log === void 0 ? void 0 : Log.debug('search device end ======================\n');
672
663
  }
673
664
  else if (displayName && /\bpro\s*2\b/i.test(displayName)) {
674
665
  Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Pro2-like BLE device was not accepted:', {
@@ -679,10 +670,15 @@ class ReactNativeBleTransport {
679
670
  });
680
671
  }
681
672
  });
682
- getConnectedDeviceIds(getBluetoothServiceUuids()).then(devices => {
673
+ getConnectedDeviceIds(reactNative.Platform.OS === 'ios' ? getBluetoothServiceUuids() : []).then(devices => {
683
674
  for (const device of devices) {
684
- Log === null || Log === void 0 ? void 0 : Log.debug('search connected peripheral: ', device.id);
685
- addDevice(device);
675
+ const { serviceUUIDs } = device;
676
+ const hasCachedServiceUuid = Boolean(serviceUUIDs === null || serviceUUIDs === void 0 ? void 0 : serviceUUIDs.length);
677
+ const keepDevice = reactNative.Platform.OS === 'ios' || hasCachedServiceUuid;
678
+ if (keepDevice) {
679
+ Log === null || Log === void 0 ? void 0 : Log.debug('search connected peripheral: ', device.id);
680
+ addDevice(device);
681
+ }
686
682
  }
687
683
  });
688
684
  const addDevice = (device) => {
@@ -694,6 +690,12 @@ class ReactNativeBleTransport {
694
690
  this.deviceProtocolHints.set(device.id, protocolHint);
695
691
  }
696
692
  deviceList.push(Object.assign(Object.assign({}, device), { name: displayName, commType: 'ble' }));
693
+ Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] OneKey BLE device discovered', {
694
+ deviceId: device.id,
695
+ name: displayName,
696
+ serviceUUIDs: device.serviceUUIDs,
697
+ protocolHint,
698
+ });
697
699
  }
698
700
  };
699
701
  timer.timeout(() => {
@@ -729,7 +731,6 @@ class ReactNativeBleTransport {
729
731
  this.runPromise.reject(error);
730
732
  this.rejectAllProtocolV2Frames(error);
731
733
  this.runPromise = null;
732
- this.activeProtocolV2Call = null;
733
734
  Log === null || Log === void 0 ? void 0 : Log.debug('Force clean Bluetooth run promise, forceCleanRunPromise: ', forceCleanRunPromise);
734
735
  }
735
736
  const blePlxManager = yield this.getPlxManager();
@@ -854,7 +855,7 @@ class ReactNativeBleTransport {
854
855
  let bufferLength = 0;
855
856
  let buffer$1 = [];
856
857
  const subscription = characteristic.monitor((error, c) => {
857
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
858
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
858
859
  const isCurrentMonitor = this.monitorTokens.get(uuid) === monitorToken;
859
860
  if (error) {
860
861
  Log === null || Log === void 0 ? void 0 : Log.debug(`error monitor ${characteristic.uuid}, deviceId: ${characteristic.deviceID}: ${error}`);
@@ -866,19 +867,37 @@ class ReactNativeBleTransport {
866
867
  Log === null || Log === void 0 ? void 0 : Log.debug('monitor error ignored for stale transport: ', uuid, notifyTransactionId);
867
868
  return;
868
869
  }
869
- if (this.runPromise) {
870
- let ERROR = hdShared.HardwareErrorCode.BleCharacteristicNotifyError;
870
+ if (this.deviceProtocol.get(uuid) === 'V2') {
871
+ let errorCode = hdShared.HardwareErrorCode.BleCharacteristicNotifyError;
871
872
  if ((_a = error.reason) === null || _a === void 0 ? void 0 : _a.includes('The connection has timed out unexpectedly')) {
872
- ERROR = hdShared.HardwareErrorCode.BleTimeoutError;
873
+ errorCode = hdShared.HardwareErrorCode.BleTimeoutError;
873
874
  }
874
- if ((_b = error.reason) === null || _b === void 0 ? void 0 : _b.includes('Encryption is insufficient')) {
875
- ERROR = hdShared.HardwareErrorCode.BleDeviceBondError;
875
+ else if ((_b = error.reason) === null || _b === void 0 ? void 0 : _b.includes('Encryption is insufficient')) {
876
+ errorCode = hdShared.HardwareErrorCode.BleDeviceBondError;
876
877
  }
877
- if (((_c = error.reason) === null || _c === void 0 ? void 0 : _c.includes('Cannot write client characteristic config descriptor')) ||
878
+ else if (((_c = error.reason) === null || _c === void 0 ? void 0 : _c.includes('Cannot write client characteristic config descriptor')) ||
878
879
  ((_d = error.reason) === null || _d === void 0 ? void 0 : _d.includes('Cannot find client characteristic config descriptor')) ||
879
880
  ((_e = error.reason) === null || _e === void 0 ? void 0 : _e.includes('The handle is invalid')) ||
880
881
  ((_f = error.reason) === null || _f === void 0 ? void 0 : _f.includes('Writing is not permitted')) ||
881
882
  ((_g = error.reason) === null || _g === void 0 ? void 0 : _g.includes('notify change failed for device'))) {
883
+ errorCode = hdShared.HardwareErrorCode.BleCharacteristicNotifyChangeFailure;
884
+ }
885
+ this.rejectProtocolV2Frames(uuid, hdShared.ERRORS.TypedError(errorCode));
886
+ return;
887
+ }
888
+ if (this.runPromise) {
889
+ let ERROR = hdShared.HardwareErrorCode.BleCharacteristicNotifyError;
890
+ if ((_h = error.reason) === null || _h === void 0 ? void 0 : _h.includes('The connection has timed out unexpectedly')) {
891
+ ERROR = hdShared.HardwareErrorCode.BleTimeoutError;
892
+ }
893
+ if ((_j = error.reason) === null || _j === void 0 ? void 0 : _j.includes('Encryption is insufficient')) {
894
+ ERROR = hdShared.HardwareErrorCode.BleDeviceBondError;
895
+ }
896
+ if (((_k = error.reason) === null || _k === void 0 ? void 0 : _k.includes('Cannot write client characteristic config descriptor')) ||
897
+ ((_l = error.reason) === null || _l === void 0 ? void 0 : _l.includes('Cannot find client characteristic config descriptor')) ||
898
+ ((_m = error.reason) === null || _m === void 0 ? void 0 : _m.includes('The handle is invalid')) ||
899
+ ((_o = error.reason) === null || _o === void 0 ? void 0 : _o.includes('Writing is not permitted')) ||
900
+ ((_p = error.reason) === null || _p === void 0 ? void 0 : _p.includes('notify change failed for device'))) {
882
901
  const notifyError = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleCharacteristicNotifyChangeFailure);
883
902
  this.runPromise.reject(notifyError);
884
903
  this.rejectAllProtocolV2Frames(notifyError);
@@ -907,7 +926,7 @@ class ReactNativeBleTransport {
907
926
  return;
908
927
  }
909
928
  if (protocol === 'V2') {
910
- this.handleProtocolV2Notification(uuid, new Uint8Array(data));
929
+ this.handleProtocolV2Notification(uuid, monitorToken, new Uint8Array(data));
911
930
  return;
912
931
  }
913
932
  if (isHeaderChunk(data)) {
@@ -921,28 +940,32 @@ class ReactNativeBleTransport {
921
940
  const value = buffer.Buffer.from(buffer$1);
922
941
  bufferLength = 0;
923
942
  buffer$1 = [];
924
- (_h = this.runPromise) === null || _h === void 0 ? void 0 : _h.resolve(value.toString('hex'));
943
+ (_q = this.runPromise) === null || _q === void 0 ? void 0 : _q.resolve(value.toString('hex'));
925
944
  }
926
945
  }
927
946
  catch (error) {
928
947
  Log === null || Log === void 0 ? void 0 : Log.debug('monitor data error: ', error);
929
948
  const notifyError = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleWriteCharacteristicError);
930
- (_j = this.runPromise) === null || _j === void 0 ? void 0 : _j.reject(notifyError);
931
- this.rejectAllProtocolV2Frames(notifyError);
949
+ if (this.deviceProtocol.get(uuid) === 'V2') {
950
+ this.rejectProtocolV2Frames(uuid, notifyError);
951
+ }
952
+ else {
953
+ (_r = this.runPromise) === null || _r === void 0 ? void 0 : _r.reject(notifyError);
954
+ }
932
955
  }
933
956
  }, notifyTransactionId);
934
957
  return subscription;
935
958
  }
936
959
  release(uuid, onclose = false) {
937
- var _a, _b, _c, _d, _e, _f, _g, _h;
960
+ var _a, _b, _c, _d, _e, _f, _g;
938
961
  return __awaiter(this, void 0, void 0, function* () {
939
962
  const transport = transportCache[uuid];
963
+ yield this.protocolV2Links.invalidateLink(uuid, 'React Native BLE transport released');
940
964
  if (this.runPromise) {
941
965
  const error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleForceCleanRunPromise);
942
966
  this.runPromise.reject(error);
943
967
  this.runPromise = null;
944
968
  this.rejectAllProtocolV2Frames(error);
945
- this.activeProtocolV2Call = null;
946
969
  }
947
970
  else {
948
971
  this.resetProtocolV2Frames(uuid);
@@ -950,9 +973,6 @@ class ReactNativeBleTransport {
950
973
  if (reactNative.Platform.OS === 'android' && !onclose && transport) {
951
974
  (_a = this.protocolV2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
952
975
  this.resetProtocolV2Frames(uuid);
953
- if (((_b = this.activeProtocolV2Call) === null || _b === void 0 ? void 0 : _b.uuid) === uuid) {
954
- this.activeProtocolV2Call = null;
955
- }
956
976
  return Promise.resolve(true);
957
977
  }
958
978
  if (transport) {
@@ -960,14 +980,14 @@ class ReactNativeBleTransport {
960
980
  this.monitorTokens.delete(uuid);
961
981
  }
962
982
  Log === null || Log === void 0 ? void 0 : Log.debug('release: removing disconnect subscription for device: ', uuid);
963
- (_c = transport.disconnectSubscription) === null || _c === void 0 ? void 0 : _c.remove();
983
+ (_b = transport.disconnectSubscription) === null || _b === void 0 ? void 0 : _b.remove();
964
984
  transport.disconnectSubscription = undefined;
965
- Log === null || Log === void 0 ? void 0 : Log.debug('release: removing notify subscription, characteristic: ', (_d = transport.notifyCharacteristic) === null || _d === void 0 ? void 0 : _d.uuid);
966
- (_e = transport.notifySubscription) === null || _e === void 0 ? void 0 : _e.remove();
985
+ Log === null || Log === void 0 ? void 0 : Log.debug('release: removing notify subscription, characteristic: ', (_c = transport.notifyCharacteristic) === null || _c === void 0 ? void 0 : _c.uuid);
986
+ (_d = transport.notifySubscription) === null || _d === void 0 ? void 0 : _d.remove();
967
987
  transport.notifySubscription = undefined;
968
988
  if (transport.notifyTransactionId) {
969
989
  try {
970
- yield ((_f = this.blePlxManager) === null || _f === void 0 ? void 0 : _f.cancelTransaction(transport.notifyTransactionId));
990
+ yield ((_e = this.blePlxManager) === null || _e === void 0 ? void 0 : _e.cancelTransaction(transport.notifyTransactionId));
971
991
  }
972
992
  catch (e) {
973
993
  Log === null || Log === void 0 ? void 0 : Log.debug('release: cancel notify transaction error (ignored): ', (e === null || e === void 0 ? void 0 : e.message) || e);
@@ -976,12 +996,11 @@ class ReactNativeBleTransport {
976
996
  delete transportCache[uuid];
977
997
  }
978
998
  this.deviceProtocol.delete(uuid);
979
- this.deviceProtocolHints.delete(uuid);
980
- (_g = this.protocolV2Assemblers.get(uuid)) === null || _g === void 0 ? void 0 : _g.reset();
999
+ (_f = this.protocolV2Assemblers.get(uuid)) === null || _f === void 0 ? void 0 : _f.reset();
981
1000
  this.protocolV2Assemblers.delete(uuid);
982
1001
  this.resetProtocolV2Frames(uuid);
983
1002
  try {
984
- yield ((_h = this.blePlxManager) === null || _h === void 0 ? void 0 : _h.cancelTransaction(uuid));
1003
+ yield ((_g = this.blePlxManager) === null || _g === void 0 ? void 0 : _g.cancelTransaction(uuid));
985
1004
  }
986
1005
  catch (e) {
987
1006
  Log === null || Log === void 0 ? void 0 : Log.debug('release: cancel transaction error (ignored): ', (e === null || e === void 0 ? void 0 : e.message) || e);
@@ -1002,30 +1021,18 @@ class ReactNativeBleTransport {
1002
1021
  if (this._messages == null) {
1003
1022
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.TransportNotConfigured);
1004
1023
  }
1005
- const forceRun = name === 'Initialize' || name === 'Cancel';
1006
- Log === null || Log === void 0 ? void 0 : Log.debug('transport-react-native call this.runPromise', this.runPromise);
1007
- if (this.runPromise && !forceRun) {
1008
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.TransportCallInProgress);
1009
- }
1010
1024
  const protocol = this.getProtocolType(uuid);
1011
1025
  if (!protocol) {
1012
1026
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Device protocol has not been detected for ${uuid}`);
1013
1027
  }
1014
- if (name === 'ResourceUpdate' || name === 'ResourceAck') {
1015
- Log === null || Log === void 0 ? void 0 : Log.debug('transport-react-native', 'call-', ' name: ', name, ' data: ', {
1016
- file_name: data === null || data === void 0 ? void 0 : data.file_name,
1017
- hash: data === null || data === void 0 ? void 0 : data.hash,
1018
- });
1019
- }
1020
- else if (transport.LogBlockCommand.has(name)) {
1021
- Log === null || Log === void 0 ? void 0 : Log.debug('transport-react-native', 'call-', ' name: ', name, ' protocol: ', protocol);
1022
- }
1023
- else {
1024
- Log === null || Log === void 0 ? void 0 : Log.debug('transport-react-native', 'call-', ' name: ', name, ' data: ', data, ' protocol: ', protocol);
1025
- }
1028
+ Log === null || Log === void 0 ? void 0 : Log.debug('transport call', createTransportCallLog(name, protocol, data));
1026
1029
  if (protocol === 'V2') {
1027
1030
  return this.callProtocolV2(uuid, name, data, options);
1028
1031
  }
1032
+ const forceRun = name === 'Initialize' || name === 'Cancel';
1033
+ if (this.runPromise && !forceRun) {
1034
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.TransportCallInProgress);
1035
+ }
1029
1036
  return this.callProtocolV1(uuid, name, data, options);
1030
1037
  });
1031
1038
  }
@@ -1101,7 +1108,7 @@ class ReactNativeBleTransport {
1101
1108
  });
1102
1109
  }
1103
1110
  else if (name === 'FirmwareUpload') {
1104
- Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] FirmwareUpload write uses throttled BLE packets:', {
1111
+ Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Firmware upload transport configured', {
1105
1112
  packetCapacity: FIRMWARE_UPLOAD_WRITE_PACKET_CAPACITY,
1106
1113
  burstSize: FIRMWARE_UPLOAD_WRITE_BURST_SIZE,
1107
1114
  pauseMs: FIRMWARE_UPLOAD_WRITE_PAUSE_MS,
@@ -1190,7 +1197,6 @@ class ReactNativeBleTransport {
1190
1197
  if (typeof response !== 'string') {
1191
1198
  throw new Error('Returning data is not string.');
1192
1199
  }
1193
- Log === null || Log === void 0 ? void 0 : Log.debug('receive data: ', response);
1194
1200
  const jsonData = ProtocolV1.decodeMessage(messages, response);
1195
1201
  return check.call(jsonData);
1196
1202
  }
@@ -1216,9 +1222,9 @@ class ReactNativeBleTransport {
1216
1222
  this.stopped = true;
1217
1223
  }
1218
1224
  disconnect(session) {
1219
- var _a, _b, _c, _d, _e, _f;
1225
+ var _a, _b, _c, _d, _e;
1220
1226
  return __awaiter(this, void 0, void 0, function* () {
1221
- Log === null || Log === void 0 ? void 0 : Log.debug('transport-react-native transport resetSession: ', session);
1227
+ yield this.protocolV2Links.invalidateLink(session, 'React Native BLE transport disconnected');
1222
1228
  const transport = transportCache[session];
1223
1229
  if (transport === null || transport === void 0 ? void 0 : transport.disconnectSubscription) {
1224
1230
  try {
@@ -1269,12 +1275,9 @@ class ReactNativeBleTransport {
1269
1275
  this.deviceProtocolHints.delete(session);
1270
1276
  this.protocolV2Assemblers.delete(session);
1271
1277
  this.resetProtocolV2Frames(session);
1272
- if (((_d = this.activeProtocolV2Call) === null || _d === void 0 ? void 0 : _d.uuid) === session) {
1273
- this.activeProtocolV2Call = null;
1274
- }
1275
1278
  try {
1276
- (_e = this.emitter) === null || _e === void 0 ? void 0 : _e.emit('device-disconnect', {
1277
- name: (_f = transport === null || transport === void 0 ? void 0 : transport.device) === null || _f === void 0 ? void 0 : _f.name,
1279
+ (_d = this.emitter) === null || _d === void 0 ? void 0 : _d.emit('device-disconnect', {
1280
+ name: (_e = transport === null || transport === void 0 ? void 0 : transport.device) === null || _e === void 0 ? void 0 : _e.name,
1278
1281
  id: session,
1279
1282
  connectId: session,
1280
1283
  });
@@ -1313,14 +1316,22 @@ class ReactNativeBleTransport {
1313
1316
  if (expectedProtocol === 'V1') {
1314
1317
  if (yield this.probeProtocolV1(uuid)) {
1315
1318
  this.deviceProtocol.set(uuid, 'V1');
1316
- Log === null || Log === void 0 ? void 0 : Log.debug(`[ReactNativeBleTransport] detectProtocol: uuid=${uuid} -> V1 (expected)`);
1319
+ Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] protocol detected', {
1320
+ deviceId: uuid,
1321
+ protocol: 'V1',
1322
+ source: 'expected',
1323
+ });
1317
1324
  return 'V1';
1318
1325
  }
1319
1326
  throw this.createProtocolMismatchError(expectedProtocol);
1320
1327
  }
1321
1328
  if (expectedProtocol === 'V2') {
1322
1329
  this.deviceProtocol.set(uuid, 'V2');
1323
- Log === null || Log === void 0 ? void 0 : Log.debug(`[ReactNativeBleTransport] detectProtocol: uuid=${uuid} -> V2 (expected)`);
1330
+ Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] protocol detected', {
1331
+ deviceId: uuid,
1332
+ protocol: 'V2',
1333
+ source: 'expected',
1334
+ });
1324
1335
  return 'V2';
1325
1336
  }
1326
1337
  const probeOrder = protocolHint === 'V2' || this.deviceProtocol.get(uuid) === 'V2' ? ['V2', 'V1'] : ['V1', 'V2'];
@@ -1332,7 +1343,11 @@ class ReactNativeBleTransport {
1332
1343
  const detected = protocol === 'V1' ? yield this.probeProtocolV1(uuid) : yield this.probeProtocolV2(uuid);
1333
1344
  if (detected) {
1334
1345
  this.deviceProtocol.set(uuid, protocol);
1335
- Log === null || Log === void 0 ? void 0 : Log.debug(`[ReactNativeBleTransport] detectProtocol: uuid=${uuid} -> ${protocol}`);
1346
+ Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] protocol detected', {
1347
+ deviceId: uuid,
1348
+ protocol,
1349
+ source: 'probe',
1350
+ });
1336
1351
  return protocol;
1337
1352
  }
1338
1353
  }
@@ -1341,14 +1356,12 @@ class ReactNativeBleTransport {
1341
1356
  });
1342
1357
  }
1343
1358
  resetProbeStateAfterProtocolProbe(uuid, protocol) {
1344
- var _a, _b, _c, _d;
1359
+ var _a, _b, _c;
1345
1360
  return __awaiter(this, void 0, void 0, function* () {
1346
1361
  const transport = transportCache[uuid];
1362
+ yield this.protocolV2Links.invalidateLink(uuid, `Reset notify state after Protocol ${protocol} probe`);
1347
1363
  (_a = this.protocolV2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
1348
1364
  this.resetProtocolV2Frames(uuid);
1349
- if (((_b = this.activeProtocolV2Call) === null || _b === void 0 ? void 0 : _b.uuid) === uuid) {
1350
- this.activeProtocolV2Call = null;
1351
- }
1352
1365
  if (this.runPromise) {
1353
1366
  const error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleForceCleanRunPromise);
1354
1367
  this.runPromise.reject(error);
@@ -1360,11 +1373,11 @@ class ReactNativeBleTransport {
1360
1373
  if (this.monitorTokens.get(uuid) === transport.monitorToken) {
1361
1374
  this.monitorTokens.delete(uuid);
1362
1375
  }
1363
- (_c = transport.notifySubscription) === null || _c === void 0 ? void 0 : _c.remove();
1376
+ (_b = transport.notifySubscription) === null || _b === void 0 ? void 0 : _b.remove();
1364
1377
  transport.notifySubscription = undefined;
1365
1378
  if (previousNotifyTransactionId) {
1366
1379
  try {
1367
- yield ((_d = this.blePlxManager) === null || _d === void 0 ? void 0 : _d.cancelTransaction(previousNotifyTransactionId));
1380
+ yield ((_c = this.blePlxManager) === null || _c === void 0 ? void 0 : _c.cancelTransaction(previousNotifyTransactionId));
1368
1381
  }
1369
1382
  catch (error) {
1370
1383
  Log === null || Log === void 0 ? void 0 : Log.debug(`[ReactNativeBleTransport] cancel notify after Protocol ${protocol} probe failed:`, (error === null || error === void 0 ? void 0 : error.message) || error);
@@ -1426,14 +1439,10 @@ class ReactNativeBleTransport {
1426
1439
  return detected;
1427
1440
  });
1428
1441
  }
1429
- handleProtocolV2Notification(uuid, data) {
1430
- var _a, _b, _c;
1442
+ handleProtocolV2Notification(uuid, monitorToken, data) {
1431
1443
  try {
1432
- if (!this.runPromise || ((_a = this.activeProtocolV2Call) === null || _a === void 0 ? void 0 : _a.uuid) !== uuid) {
1433
- (_b = this.protocolV2Assemblers.get(uuid)) === null || _b === void 0 ? void 0 : _b.reset();
1434
- this.resetProtocolV2Frames(uuid);
1444
+ if (this.monitorTokens.get(uuid) !== monitorToken)
1435
1445
  return;
1436
- }
1437
1446
  if (data.length === 0)
1438
1447
  return;
1439
1448
  const assembler = this.protocolV2Assemblers.get(uuid);
@@ -1446,8 +1455,10 @@ class ReactNativeBleTransport {
1446
1455
  catch (error) {
1447
1456
  Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V2 notification error:', error);
1448
1457
  const notifyError = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleWriteCharacteristicError);
1449
- (_c = this.runPromise) === null || _c === void 0 ? void 0 : _c.reject(notifyError);
1450
- this.rejectAllProtocolV2Frames(notifyError);
1458
+ this.rejectProtocolV2Frames(uuid, notifyError);
1459
+ this.protocolV2Links
1460
+ .invalidateLink(uuid, `Protocol V2 notification error: ${error}`)
1461
+ .catch(invalidateError => Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V2 notify cleanup failed:', invalidateError));
1451
1462
  }
1452
1463
  }
1453
1464
  getProtocolV2FrameQueue(uuid) {
@@ -1478,9 +1489,13 @@ class ReactNativeBleTransport {
1478
1489
  this.protocolV2FrameQueues.delete(uuid);
1479
1490
  this.protocolV2FramePromises.delete(uuid);
1480
1491
  }
1481
- isActiveProtocolV2Call(uuid, token) {
1482
- var _a;
1483
- return ((_a = this.activeProtocolV2Call) === null || _a === void 0 ? void 0 : _a.uuid) === uuid && this.activeProtocolV2Call.token === token;
1492
+ rejectProtocolV2Frames(uuid, error) {
1493
+ this.protocolV2FrameQueues.delete(uuid);
1494
+ const framePromise = this.protocolV2FramePromises.get(uuid);
1495
+ if (framePromise) {
1496
+ this.protocolV2FramePromises.delete(uuid);
1497
+ framePromise.reject(error);
1498
+ }
1484
1499
  }
1485
1500
  readProtocolV2Frame(uuid) {
1486
1501
  return __awaiter(this, void 0, void 0, function* () {
@@ -1500,7 +1515,7 @@ class ReactNativeBleTransport {
1500
1515
  }
1501
1516
  });
1502
1517
  }
1503
- writeProtocolV2Frame(transport, frame, options) {
1518
+ writeProtocolV2Frame(transport, frame) {
1504
1519
  return __awaiter(this, void 0, void 0, function* () {
1505
1520
  const tuning = getProtocolV2BleTuning();
1506
1521
  const packetCapacity = resolveProtocolV2PacketCapacity({
@@ -1509,131 +1524,79 @@ class ReactNativeBleTransport {
1509
1524
  androidPacketLength: tuning.androidPacketLength,
1510
1525
  mtu: reactNative.Platform.OS === 'android' ? transport.mtuSize : undefined,
1511
1526
  });
1512
- const writeWithResponse = !!(options === null || options === void 0 ? void 0 : options.writeWithResponse) || (!!(options === null || options === void 0 ? void 0 : options.highVolume) && tuning.highVolumeWriteWithResponse);
1513
- const writeMode = resolveBleWriteMode(transport.writeCharacteristic, writeWithResponse ? 'withResponse' : 'withoutResponse');
1514
- const shouldThrottle = !!(options === null || options === void 0 ? void 0 : options.highVolume) && writeMode === 'withoutResponse';
1515
- let packetsWritten = 0;
1516
- try {
1517
- for (let offset = 0; offset < frame.length; offset += packetCapacity) {
1518
- const chunk = frame.slice(offset, offset + packetCapacity);
1519
- const base64 = buffer.Buffer.from(chunk).toString('base64');
1520
- if (writeMode === 'withResponse') {
1521
- yield transport.writeCharacteristic.writeWithResponse(base64);
1522
- }
1523
- else {
1524
- yield transport.writeCharacteristic.writeWithoutResponse(base64);
1525
- }
1526
- packetsWritten += 1;
1527
- if (shouldThrottle &&
1528
- packetsWritten % tuning.highVolumeWriteBurstSize === 0 &&
1529
- offset + packetCapacity < frame.length) {
1530
- yield delay(tuning.highVolumeWritePauseMs);
1531
- }
1532
- }
1533
- if (shouldThrottle) {
1534
- yield delay(tuning.highVolumeWriteFlushDelayMs);
1535
- }
1536
- }
1537
- catch (error) {
1538
- if ((options === null || options === void 0 ? void 0 : options.highVolume) && !writeWithResponse && packetsWritten === 0) {
1539
- Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V2 high-volume writeWithoutResponse failed before data was sent, fallback to writeWithResponse:', error);
1540
- yield this.writeProtocolV2Frame(transport, frame, {
1541
- highVolume: true,
1542
- writeWithResponse: true,
1543
- });
1544
- return;
1545
- }
1546
- throw error;
1527
+ for (let offset = 0; offset < frame.length; offset += packetCapacity) {
1528
+ const chunk = frame.slice(offset, offset + packetCapacity);
1529
+ const base64 = buffer.Buffer.from(chunk).toString('base64');
1530
+ yield transport.writeCharacteristic.writeWithoutResponse(base64);
1547
1531
  }
1548
1532
  });
1549
1533
  }
1550
1534
  callProtocolV2(uuid, name, data, options) {
1551
- var _a, _b, _c, _d;
1535
+ var _a;
1552
1536
  return __awaiter(this, void 0, void 0, function* () {
1553
1537
  if (!this._messages || !this._messagesV2) {
1554
1538
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.TransportNotConfigured);
1555
1539
  }
1556
- const forceRun = name === 'Initialize' || name === 'Cancel' || name === 'Ping';
1557
- if (this.runPromise) {
1558
- if (!forceRun) {
1559
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.TransportCallInProgress);
1560
- }
1561
- const error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleForceCleanRunPromise);
1562
- this.runPromise.reject(error);
1563
- this.rejectAllProtocolV2Frames(error);
1564
- this.runPromise = null;
1565
- this.activeProtocolV2Call = null;
1566
- }
1567
- const transport$1 = this.getCachedTransport(uuid);
1568
- const runPromise = hdShared.createDeferred();
1569
- runPromise.promise.catch(() => undefined);
1570
- this.runPromise = runPromise;
1571
- const callToken = this.nextProtocolV2CallToken++;
1572
- this.activeProtocolV2Call = { uuid, token: callToken };
1573
- (_a = this.protocolV2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
1574
- this.resetProtocolV2Frames(uuid);
1575
- let completed = false;
1576
- const callOptions = Object.assign(Object.assign({}, options), { timeoutMs: (_b = options === null || options === void 0 ? void 0 : options.timeoutMs) !== null && _b !== void 0 ? _b : BLE_RESPONSE_TIMEOUT_MS });
1540
+ const callOptions = Object.assign(Object.assign({}, options), { timeoutMs: (_a = options === null || options === void 0 ? void 0 : options.timeoutMs) !== null && _a !== void 0 ? _a : BLE_RESPONSE_TIMEOUT_MS });
1577
1541
  const highVolumeWrite = transport.LogBlockCommand.has(name);
1578
1542
  if (highVolumeWrite) {
1579
1543
  const tuning = getProtocolV2BleTuning();
1580
- Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V2 high-volume write uses throttled writeWithoutResponse:', name, {
1544
+ Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V2 high-volume write configured', {
1545
+ name,
1546
+ writeMode: 'withoutResponse',
1581
1547
  packetCapacity: reactNative.Platform.OS === 'ios' ? tuning.iosPacketLength : tuning.androidPacketLength,
1582
- burstSize: tuning.highVolumeWriteBurstSize,
1583
- pauseMs: tuning.highVolumeWritePauseMs,
1584
- flushDelayMs: tuning.highVolumeWriteFlushDelayMs,
1585
- writeWithResponse: tuning.highVolumeWriteWithResponse,
1586
1548
  });
1587
1549
  }
1588
1550
  try {
1589
- const session = new transport.ProtocolV2Session({
1590
- schemas: {
1591
- protocolV1: this._messages,
1592
- protocolV2: this._messagesV2,
1593
- },
1594
- router: transport.PROTOCOL_V2_CHANNEL_BLE_UART,
1595
- writeFrame: (frame) => __awaiter(this, void 0, void 0, function* () {
1596
- yield this.writeProtocolV2Frame(transport$1, frame, {
1597
- highVolume: highVolumeWrite,
1598
- });
1599
- }),
1600
- readFrame: () => __awaiter(this, void 0, void 0, function* () {
1601
- const rxFrame = yield this.readProtocolV2Frame(uuid);
1602
- if (!(rxFrame instanceof Uint8Array)) {
1603
- throw new Error('Protocol V2 response is not Uint8Array');
1604
- }
1605
- return rxFrame;
1606
- }),
1607
- logger: Log,
1608
- logPrefix: 'ProtocolV2 RN-BLE',
1609
- createTimeoutError: (_messageName, timeout) => hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleTimeoutError, `BLE response timeout after ${timeout}ms for ${name}`),
1610
- });
1611
- const result = yield session.call(name, data, callOptions);
1612
- completed = true;
1613
- return result;
1551
+ return yield this.protocolV2Links.call(uuid, () => this.createProtocolV2Adapter(uuid), name, data, callOptions);
1614
1552
  }
1615
1553
  catch (e) {
1616
- if (this.isActiveProtocolV2Call(uuid, callToken)) {
1617
- (_c = this.protocolV2Assemblers.get(uuid)) === null || _c === void 0 ? void 0 : _c.reset();
1618
- this.resetProtocolV2Frames(uuid);
1619
- }
1620
1554
  Log === null || Log === void 0 ? void 0 : Log.error('[ReactNativeBleTransport] Protocol V2 call error:', e);
1621
1555
  throw e;
1622
1556
  }
1623
- finally {
1624
- if (this.isActiveProtocolV2Call(uuid, callToken)) {
1625
- if (!completed) {
1626
- (_d = this.protocolV2Assemblers.get(uuid)) === null || _d === void 0 ? void 0 : _d.reset();
1627
- }
1628
- this.resetProtocolV2Frames(uuid);
1629
- this.activeProtocolV2Call = null;
1630
- }
1631
- if (this.runPromise === runPromise) {
1632
- this.runPromise = null;
1633
- }
1634
- }
1635
1557
  });
1636
1558
  }
1559
+ createProtocolV2Adapter(uuid) {
1560
+ var _a;
1561
+ const generation = (_a = this.monitorTokens.get(uuid)) !== null && _a !== void 0 ? _a : 0;
1562
+ const assertCurrentGeneration = () => {
1563
+ if (this.monitorTokens.get(uuid) !== generation) {
1564
+ throw new Error(`Protocol V2 monitor generation changed for ${uuid}`);
1565
+ }
1566
+ };
1567
+ return {
1568
+ router: transport.PROTOCOL_V2_CHANNEL_BLE_UART,
1569
+ maxFrameBytes: transport.PROTOCOL_V2_BLE_FRAME_MAX_BYTES,
1570
+ generation,
1571
+ prepareCall: () => {
1572
+ var _a;
1573
+ assertCurrentGeneration();
1574
+ (_a = this.protocolV2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
1575
+ this.resetProtocolV2Frames(uuid);
1576
+ },
1577
+ writeFrame: (frame) => __awaiter(this, void 0, void 0, function* () {
1578
+ assertCurrentGeneration();
1579
+ const currentTransport = this.getCachedTransport(uuid);
1580
+ yield this.writeProtocolV2Frame(currentTransport, frame);
1581
+ }),
1582
+ readFrame: () => __awaiter(this, void 0, void 0, function* () {
1583
+ assertCurrentGeneration();
1584
+ const rxFrame = yield this.readProtocolV2Frame(uuid);
1585
+ if (!(rxFrame instanceof Uint8Array)) {
1586
+ throw new Error('Protocol V2 response is not Uint8Array');
1587
+ }
1588
+ return rxFrame;
1589
+ }),
1590
+ reset: (reason) => {
1591
+ var _a;
1592
+ (_a = this.protocolV2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
1593
+ this.rejectProtocolV2Frames(uuid, new Error(reason));
1594
+ },
1595
+ logger: Log,
1596
+ logPrefix: 'ProtocolV2 RN-BLE',
1597
+ createTimeoutError: (messageName, timeout) => hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleTimeoutError, `BLE response timeout after ${timeout}ms for ${messageName}`),
1598
+ };
1599
+ }
1637
1600
  getProtocolType(path) {
1638
1601
  return this.deviceProtocol.get(path);
1639
1602
  }