@onekeyfe/hd-transport-react-native 1.2.0-alpha.68 → 1.2.0-alpha.69

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
@@ -93,7 +93,8 @@ const onDeviceBondState = (bleMacAddress) => new Promise((resolve, reject) => {
93
93
 
94
94
  const IOS_PACKET_LENGTH = 128;
95
95
  const ANDROID_PACKET_LENGTH = 192;
96
- const ANDROID_DEFAULT_MTU = 23;
96
+ const IOS_PROTOCOL_V2_PACKET_LENGTH = 244;
97
+ const ANDROID_PROTOCOL_V2_PACKET_LENGTH = 514;
97
98
  const ClassicServiceUUID = '00000001-0000-1000-8000-00805f9b34fb';
98
99
  const OneKeyServices = {
99
100
  classic: {
@@ -134,15 +135,20 @@ const isSameBleUuid = (left, right) => {
134
135
  function hasWritableCapability(characteristic) {
135
136
  return !!(characteristic.isWritableWithResponse || characteristic.isWritableWithoutResponse);
136
137
  }
137
- function resolveProtocolV2PacketCapacity({ platform, iosPacketLength = IOS_PACKET_LENGTH, androidPacketLength = ANDROID_PACKET_LENGTH, mtu, }) {
138
- if (platform === 'ios') {
139
- return iosPacketLength;
138
+ function resolveProtocolV2PacketCapacity({ platform, iosPacketLength = IOS_PROTOCOL_V2_PACKET_LENGTH, androidPacketLength = ANDROID_PROTOCOL_V2_PACKET_LENGTH, mtu, }) {
139
+ if (typeof mtu !== 'number' || !Number.isFinite(mtu) || mtu <= 3) {
140
+ throw new Error(`Protocol V2 BLE requires a negotiated MTU, received: ${String(mtu)}`);
140
141
  }
141
- if (platform === 'android') {
142
- const payloadLength = Math.max((mtu !== null && mtu !== void 0 ? mtu : ANDROID_DEFAULT_MTU) - 3, 1);
143
- return Math.min(androidPacketLength, payloadLength);
144
- }
145
- return androidPacketLength;
142
+ const payloadLength = Math.floor(mtu) - 3;
143
+ const configuredPacketLength = platform === 'ios' ? iosPacketLength : androidPacketLength;
144
+ return Math.min(configuredPacketLength, payloadLength);
145
+ }
146
+ function shouldWriteProtocolV2WithResponse({ platform, highVolume, requestedWithResponse, characteristic, }) {
147
+ if (!characteristic.isWritableWithResponse)
148
+ return false;
149
+ if (!characteristic.isWritableWithoutResponse)
150
+ return true;
151
+ return requestedWithResponse === true || (platform === 'ios' && !highVolume);
146
152
  }
147
153
 
148
154
  const timer = process.env.NODE_ENV === 'development'
@@ -202,7 +208,6 @@ const isHeaderChunk = (chunk) => {
202
208
  class BleTransport {
203
209
  constructor(device, writeCharacteristic, notifyCharacteristic) {
204
210
  this.name = 'ReactNativeBleTransport';
205
- this.mtuSize = 23;
206
211
  this.id = device.id;
207
212
  this.device = device;
208
213
  this.writeCharacteristic = writeCharacteristic;
@@ -226,7 +231,6 @@ const FIRMWARE_UPLOAD_WRITE_BURST_SIZE = reactNative.Platform.OS === 'ios' ? 4 :
226
231
  const FIRMWARE_UPLOAD_WRITE_PAUSE_MS = reactNative.Platform.OS === 'ios' ? 8 : 10;
227
232
  const FIRMWARE_UPLOAD_WRITE_FLUSH_DELAY_MS = reactNative.Platform.OS === 'ios' ? 24 : 30;
228
233
  const FIRMWARE_UPLOAD_WRITE_MAX_RETRIES = 8;
229
- const IOS_PROTOCOL_V2_CONTROL_WRITE_DELAY_MS = 5;
230
234
  const ANDROID_FIRMWARE_UPLOAD_PACKET_LENGTH = 192;
231
235
  const FIRMWARE_UPLOAD_WRITE_PACKET_CAPACITY = reactNative.Platform.OS === 'ios' ? IOS_PACKET_LENGTH : ANDROID_FIRMWARE_UPLOAD_PACKET_LENGTH;
232
236
  const ANDROID_GATT_CONGESTED_STATUS = 143;
@@ -275,18 +279,12 @@ const getFirmwareUploadWriteRetryType = (error) => {
275
279
  const resolveFirmwareUploadRetryDelay = (attempt, baseDelayMs = 200, maxDelayMs = 1200) => Math.min(baseDelayMs * Math.pow(2, attempt), maxDelayMs);
276
280
  const PROTOCOL_PROBE_TIMEOUT_MS = 1000;
277
281
  const PROTOCOL_V2_PROBE_TIMEOUT_MS = 10000;
278
- const BLE_WRITE_PACKET_TIMEOUT_MS = 10000;
279
- const WEDGED_WRITE_MESSAGE = 'BLE write timeout after';
280
- const isWedgedWriteError = (error) => (error === null || error === void 0 ? void 0 : error.errorCode) === hdShared.HardwareErrorCode.BleWriteCharacteristicError &&
281
- typeof (error === null || error === void 0 ? void 0 : error.message) === 'string' &&
282
- error.message.startsWith(WEDGED_WRITE_MESSAGE);
283
- const BLE_WRITE_TIMEOUT_MANAGER_RESET_THRESHOLD = 2;
284
282
  const DEVICE_SCAN_TIMEOUT_MS = 3000;
285
283
  const IOS_NOTIFY_READY_DELAY_MS = 150;
286
284
  const ANDROID_NOTIFY_READY_DELAY_MS = 300;
287
285
  const DEFAULT_PROTOCOL_V2_BLE_TUNING = {
288
- iosPacketLength: IOS_PACKET_LENGTH,
289
- androidPacketLength: ANDROID_PACKET_LENGTH,
286
+ iosPacketLength: IOS_PROTOCOL_V2_PACKET_LENGTH,
287
+ androidPacketLength: ANDROID_PROTOCOL_V2_PACKET_LENGTH,
290
288
  };
291
289
  let protocolV2BleTuning = Object.assign({}, DEFAULT_PROTOCOL_V2_BLE_TUNING);
292
290
  const normalizePositiveInteger = (value, fallback) => {
@@ -315,25 +313,17 @@ function inferProtocolHintFromDeviceName(name) {
315
313
  function getDeviceDisplayName(device) {
316
314
  return (device === null || device === void 0 ? void 0 : device.name) || (device === null || device === void 0 ? void 0 : device.localName) || null;
317
315
  }
318
- const ANDROID_REQUEST_MTU = 256;
319
- const BLE_NATIVE_CONNECT_TIMEOUT_MS = 3000;
316
+ const IOS_REQUEST_MTU = 247;
317
+ const ANDROID_REQUEST_MTU = 517;
318
+ const BLE_MTU_REFRESH_THRESHOLD = 247;
319
+ const BLE_MTU_REFRESH_RETRY_DELAY_MS = 200;
320
+ const ANDROID_HIGH_PRIORITY_IDLE_MS = 1000;
321
+ const getRequestedBleMtu = () => reactNative.Platform.OS === 'android' ? ANDROID_REQUEST_MTU : IOS_REQUEST_MTU;
320
322
  const connectOptions = {
321
- requestMTU: ANDROID_REQUEST_MTU,
322
- timeout: BLE_NATIVE_CONNECT_TIMEOUT_MS,
323
+ requestMTU: getRequestedBleMtu(),
324
+ timeout: 3000,
323
325
  refreshGatt: 'OnConnected',
324
326
  };
325
- const fallbackConnectOptions = {
326
- timeout: BLE_NATIVE_CONNECT_TIMEOUT_MS,
327
- };
328
- const BLE_CONNECT_TIMEOUT_MS = BLE_NATIVE_CONNECT_TIMEOUT_MS * 2 + 2000;
329
- const BLE_GATT_SETUP_TIMEOUT_MS = 10000;
330
- const PROTOCOL_REPROBE_FALLBACK_ATTEMPTS = 3;
331
- const BLE_CONNECT_TIMEOUT_MANAGER_RESET_THRESHOLD = 2;
332
- const CONNECT_TIMEOUT_MESSAGE = 'BLE connect timeout after';
333
- const isConnectTimeoutError = (error) => (error === null || error === void 0 ? void 0 : error.errorCode) === hdShared.HardwareErrorCode.BleConnectedError &&
334
- typeof (error === null || error === void 0 ? void 0 : error.message) === 'string' &&
335
- error.message.startsWith(CONNECT_TIMEOUT_MESSAGE);
336
- const isNativeOperationTimeoutError = (error) => (error === null || error === void 0 ? void 0 : error.errorCode) === reactNativeBlePlx.BleErrorCode.OperationTimedOut;
337
327
  const tryToGetConfiguration = (device) => {
338
328
  if (!device || !device.serviceUUIDs)
339
329
  return null;
@@ -345,23 +335,25 @@ const tryToGetConfiguration = (device) => {
345
335
  return null;
346
336
  return infos;
347
337
  };
348
- const requestAndroidMtu = (device) => __awaiter(void 0, void 0, void 0, function* () {
349
- if (reactNative.Platform.OS !== 'android')
338
+ const requestNegotiatedMtu = (device, stage, attempt) => __awaiter(void 0, void 0, void 0, function* () {
339
+ if (reactNative.Platform.OS !== 'ios' && reactNative.Platform.OS !== 'android')
350
340
  return device;
351
341
  try {
352
- const mtuDevice = yield device.requestMTU(ANDROID_REQUEST_MTU);
353
- Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] MTU configured', {
354
- deviceId: device.id,
355
- requested: ANDROID_REQUEST_MTU,
356
- actual: mtuDevice.mtu,
357
- });
342
+ const mtuDevice = yield device.requestMTU(getRequestedBleMtu());
358
343
  return mtuDevice;
359
344
  }
360
345
  catch (error) {
361
- Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Android MTU request failed:', error);
346
+ Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] MTU refresh failed, continuing with current value', {
347
+ platform: reactNative.Platform.OS,
348
+ stage,
349
+ attempt,
350
+ actual: device.mtu,
351
+ error: error instanceof Error ? error.message : String(error),
352
+ });
362
353
  return device;
363
354
  }
364
355
  });
356
+ const resolveNegotiatedMtu = (device) => requestNegotiatedMtu(device, 'connected', 0);
365
357
  function remapError(error) {
366
358
  var _a;
367
359
  if (error instanceof reactNativeBlePlx.BleError) {
@@ -391,12 +383,7 @@ class ReactNativeBleTransport {
391
383
  this.runPromiseDeviceId = null;
392
384
  this.firmwareUploadWriteRecoveryIds = new Set();
393
385
  this.deviceProtocol = new Map();
394
- this.probingProtocols = new Map();
395
- this.writeTimeoutCounts = new Map();
396
- this.connectionSetupTimeoutCounts = new Map();
397
386
  this.deviceProtocolHints = new Map();
398
- this.sessionProtocols = new Map();
399
- this.protocolReprobeFailures = new Map();
400
387
  this.protocolV2Assemblers = new Map();
401
388
  this.protocolV2FrameQueues = new Map();
402
389
  this.protocolV2FramePromises = new Map();
@@ -423,6 +410,9 @@ class ReactNativeBleTransport {
423
410
  });
424
411
  this.monitorTokens = new Map();
425
412
  this.disconnectEventTokens = new Map();
413
+ this.protocolV2HighVolumeLogSignatures = new Map();
414
+ this.androidHighPriorityDevices = new Set();
415
+ this.androidPriorityResetTimers = new Map();
426
416
  this.nextMonitorToken = 1;
427
417
  this.scanTimeout = (_a = options.scanTimeout) !== null && _a !== void 0 ? _a : DEVICE_SCAN_TIMEOUT_MS;
428
418
  }
@@ -588,19 +578,19 @@ class ReactNativeBleTransport {
588
578
  const isConnected = yield device.isConnected().catch(() => false);
589
579
  if (!isConnected) {
590
580
  try {
591
- device = yield this.connectWithTimeout(uuid, () => device.connect(connectOptions));
581
+ device = yield device.connect(connectOptions);
592
582
  }
593
583
  catch (e) {
594
584
  if (e.errorCode === reactNativeBlePlx.BleErrorCode.DeviceMTUChangeFailed ||
595
585
  e.errorCode === reactNativeBlePlx.BleErrorCode.OperationCancelled) {
596
- device = yield this.connectWithTimeout(uuid, () => device.connect());
586
+ device = yield device.connect();
597
587
  }
598
588
  else if (e.errorCode !== reactNativeBlePlx.BleErrorCode.DeviceAlreadyConnected) {
599
589
  throw e;
600
590
  }
601
591
  }
602
592
  }
603
- const { writeCharacteristic, notifyCharacteristic } = yield this.resolveCharacteristicsWithTimeout(uuid, device);
593
+ const { writeCharacteristic, notifyCharacteristic } = yield this.resolveCharacteristics(device);
604
594
  transport.device = device;
605
595
  transport.writeCharacteristic = writeCharacteristic;
606
596
  transport.notifyCharacteristic = notifyCharacteristic;
@@ -737,11 +727,9 @@ class ReactNativeBleTransport {
737
727
  }
738
728
  installTransportForAcquire(uuid, device, characteristics) {
739
729
  return __awaiter(this, void 0, void 0, function* () {
740
- const { writeCharacteristic, notifyCharacteristic } = characteristics !== null && characteristics !== void 0 ? characteristics : (yield this.resolveCharacteristicsWithTimeout(uuid, device));
730
+ const { writeCharacteristic, notifyCharacteristic } = characteristics !== null && characteristics !== void 0 ? characteristics : (yield this.resolveCharacteristics(device));
741
731
  const transport$1 = new BleTransport(device, writeCharacteristic, notifyCharacteristic);
742
- if (reactNative.Platform.OS === 'android') {
743
- transport$1.mtuSize = typeof device.mtu === 'number' ? device.mtu : transport$1.mtuSize;
744
- }
732
+ transport$1.mtuSize = typeof device.mtu === 'number' ? device.mtu : undefined;
745
733
  const monitorToken = this.nextMonitorToken;
746
734
  this.nextMonitorToken += 1;
747
735
  const notifyTransactionId = `${uuid}:notify:${monitorToken}`;
@@ -750,6 +738,7 @@ class ReactNativeBleTransport {
750
738
  this.monitorTokens.set(uuid, monitorToken);
751
739
  transport$1.notifySubscription = this._monitorCharacteristic(transport$1.notifyCharacteristic, uuid, monitorToken, notifyTransactionId);
752
740
  transportCache[uuid] = transport$1;
741
+ this.protocolV2HighVolumeLogSignatures.set(uuid, new Set());
753
742
  this.protocolV2Assemblers.set(uuid, new transport.ProtocolV2FrameAssembler(transport.PROTOCOL_V2_BLE_FRAME_MAX_BYTES));
754
743
  if (reactNative.Platform.OS === 'ios') {
755
744
  yield new Promise(resolve => {
@@ -759,6 +748,31 @@ class ReactNativeBleTransport {
759
748
  else if (reactNative.Platform.OS === 'android') {
760
749
  yield delay(ANDROID_NOTIFY_READY_DELAY_MS);
761
750
  }
751
+ const initialMtu = transport$1.mtuSize;
752
+ let refreshAttempts = 0;
753
+ if ((reactNative.Platform.OS === 'ios' || reactNative.Platform.OS === 'android') &&
754
+ (typeof transport$1.mtuSize !== 'number' || transport$1.mtuSize < BLE_MTU_REFRESH_THRESHOLD)) {
755
+ refreshAttempts += 1;
756
+ let refreshedDevice = yield requestNegotiatedMtu(transport$1.device, 'servicesAndNotifyReady', 1);
757
+ transport$1.device = refreshedDevice;
758
+ transport$1.mtuSize =
759
+ typeof refreshedDevice.mtu === 'number' ? refreshedDevice.mtu : transport$1.mtuSize;
760
+ if (typeof transport$1.mtuSize !== 'number' || transport$1.mtuSize < BLE_MTU_REFRESH_THRESHOLD) {
761
+ yield delay(BLE_MTU_REFRESH_RETRY_DELAY_MS);
762
+ refreshAttempts += 1;
763
+ refreshedDevice = yield requestNegotiatedMtu(transport$1.device, 'servicesAndNotifyReady', 2);
764
+ transport$1.device = refreshedDevice;
765
+ transport$1.mtuSize =
766
+ typeof refreshedDevice.mtu === 'number' ? refreshedDevice.mtu : transport$1.mtuSize;
767
+ }
768
+ }
769
+ Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] BLE MTU ready', {
770
+ platform: reactNative.Platform.OS,
771
+ requested: getRequestedBleMtu(),
772
+ initial: initialMtu,
773
+ actual: transport$1.mtuSize,
774
+ refreshAttempts,
775
+ });
762
776
  return transport$1;
763
777
  });
764
778
  }
@@ -820,17 +834,14 @@ class ReactNativeBleTransport {
820
834
  if (!device) {
821
835
  Log === null || Log === void 0 ? void 0 : Log.debug('try to connect to device: ', uuid);
822
836
  try {
823
- device = yield this.connectWithTimeout(uuid, () => blePlxManager.connectToDevice(uuid, connectOptions));
837
+ device = yield blePlxManager.connectToDevice(uuid, connectOptions);
824
838
  }
825
839
  catch (e) {
826
840
  Log === null || Log === void 0 ? void 0 : Log.debug('try to connect to device has error: ', e);
827
- if (isConnectTimeoutError(e)) {
828
- throw e;
829
- }
830
841
  if (e.errorCode === reactNativeBlePlx.BleErrorCode.DeviceMTUChangeFailed ||
831
842
  e.errorCode === reactNativeBlePlx.BleErrorCode.OperationCancelled) {
832
843
  Log === null || Log === void 0 ? void 0 : Log.debug('first try to reconnect without params');
833
- device = yield this.connectWithTimeout(uuid, () => blePlxManager.connectToDevice(uuid, fallbackConnectOptions));
844
+ device = yield blePlxManager.connectToDevice(uuid);
834
845
  }
835
846
  else if (e.errorCode === reactNativeBlePlx.BleErrorCode.DeviceAlreadyConnected) {
836
847
  Log === null || Log === void 0 ? void 0 : Log.debug('device already connected');
@@ -846,27 +857,23 @@ class ReactNativeBleTransport {
846
857
  }
847
858
  if (!(yield device.isConnected())) {
848
859
  Log === null || Log === void 0 ? void 0 : Log.debug('not connected, try to connect to device: ', uuid);
849
- const disconnectedDevice = device;
850
860
  try {
851
- device = yield this.connectWithTimeout(uuid, () => disconnectedDevice.connect(connectOptions));
861
+ device = yield device.connect(connectOptions);
852
862
  }
853
863
  catch (e) {
854
864
  Log === null || Log === void 0 ? void 0 : Log.debug('not connected, try to connect to device has error: ', e);
855
- if (isConnectTimeoutError(e)) {
856
- throw e;
857
- }
858
865
  if (e.errorCode === reactNativeBlePlx.BleErrorCode.DeviceMTUChangeFailed ||
859
866
  e.errorCode === reactNativeBlePlx.BleErrorCode.OperationCancelled) {
860
867
  Log === null || Log === void 0 ? void 0 : Log.debug('second try to reconnect without params');
861
868
  try {
862
- device = yield this.connectWithTimeout(uuid, () => disconnectedDevice.connect(fallbackConnectOptions));
869
+ device = yield device.connect();
863
870
  }
864
871
  catch (e) {
865
872
  Log === null || Log === void 0 ? void 0 : Log.debug('last try to reconnect error: ', e);
866
873
  if (e.errorCode === reactNativeBlePlx.BleErrorCode.OperationCancelled) {
867
874
  Log === null || Log === void 0 ? void 0 : Log.debug('last try to reconnect');
868
- yield disconnectedDevice.cancelConnection();
869
- device = yield this.connectWithTimeout(uuid, () => disconnectedDevice.connect(fallbackConnectOptions));
875
+ yield device.cancelConnection();
876
+ device = yield device.connect();
870
877
  }
871
878
  }
872
879
  }
@@ -875,9 +882,9 @@ class ReactNativeBleTransport {
875
882
  }
876
883
  }
877
884
  }
878
- device = yield requestAndroidMtu(device);
885
+ device = yield resolveNegotiatedMtu(device);
879
886
  const acquiredDevice = device;
880
- const { writeCharacteristic, notifyCharacteristic } = yield this.resolveCharacteristicsWithTimeout(uuid, acquiredDevice);
887
+ const { writeCharacteristic, notifyCharacteristic } = yield this.resolveCharacteristics(acquiredDevice);
881
888
  const protocolHint = expectedProtocol
882
889
  ? undefined
883
890
  : (_b = (_a = input.protocolHint) !== null && _a !== void 0 ? _a : this.deviceProtocolHints.get(uuid)) !== null && _b !== void 0 ? _b : inferProtocolHintFromDeviceName(getDeviceDisplayName(acquiredDevice));
@@ -897,7 +904,7 @@ class ReactNativeBleTransport {
897
904
  if (!currentTransport) {
898
905
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.TransportNotFound);
899
906
  }
900
- this.attachDisconnectSubscription(currentTransport, acquiredDevice, uuid);
907
+ this.attachDisconnectSubscription(currentTransport, currentTransport.device, uuid);
901
908
  return { uuid, protocolType };
902
909
  }
903
910
  catch (error) {
@@ -922,7 +929,7 @@ class ReactNativeBleTransport {
922
929
  Log === null || Log === void 0 ? void 0 : Log.debug('monitor error ignored for stale transport: ', uuid, notifyTransactionId);
923
930
  return;
924
931
  }
925
- if (this.getActiveProtocol(uuid) === 'V2') {
932
+ if (this.deviceProtocol.get(uuid) === 'V2') {
926
933
  let errorCode = hdShared.HardwareErrorCode.BleCharacteristicNotifyError;
927
934
  if ((_a = error.reason) === null || _a === void 0 ? void 0 : _a.includes('The connection has timed out unexpectedly')) {
928
935
  errorCode = hdShared.HardwareErrorCode.BleTimeoutError;
@@ -973,7 +980,7 @@ class ReactNativeBleTransport {
973
980
  }
974
981
  try {
975
982
  const data = buffer.Buffer.from(c.value, 'base64');
976
- const protocol = this.getActiveProtocol(uuid);
983
+ const protocol = this.deviceProtocol.get(uuid);
977
984
  if (!protocol) {
978
985
  Log === null || Log === void 0 ? void 0 : Log.debug('monitor data ignored before protocol detection: ', uuid);
979
986
  return;
@@ -1001,7 +1008,7 @@ class ReactNativeBleTransport {
1001
1008
  catch (error) {
1002
1009
  Log === null || Log === void 0 ? void 0 : Log.debug('monitor data error: ', error);
1003
1010
  const notifyError = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleWriteCharacteristicError);
1004
- if (this.getActiveProtocol(uuid) === 'V2') {
1011
+ if (this.deviceProtocol.get(uuid) === 'V2') {
1005
1012
  this.rejectProtocolV2Frames(uuid, notifyError);
1006
1013
  }
1007
1014
  else if (this.runPromiseDeviceId === uuid) {
@@ -1036,6 +1043,7 @@ class ReactNativeBleTransport {
1036
1043
  this.resetProtocolV2Frames(uuid);
1037
1044
  return Promise.resolve(true);
1038
1045
  }
1046
+ yield this.restoreAndroidConnectionPriority(uuid, transport);
1039
1047
  if (transport) {
1040
1048
  if (this.monitorTokens.get(uuid) === transport.monitorToken) {
1041
1049
  this.monitorTokens.delete(uuid);
@@ -1056,8 +1064,8 @@ class ReactNativeBleTransport {
1056
1064
  }
1057
1065
  delete transportCache[uuid];
1058
1066
  }
1067
+ this.protocolV2HighVolumeLogSignatures.delete(uuid);
1059
1068
  this.deviceProtocol.delete(uuid);
1060
- this.probingProtocols.delete(uuid);
1061
1069
  (_f = this.protocolV2Assemblers.get(uuid)) === null || _f === void 0 ? void 0 : _f.reset();
1062
1070
  this.protocolV2Assemblers.delete(uuid);
1063
1071
  this.resetProtocolV2Frames(uuid);
@@ -1106,19 +1114,8 @@ class ReactNativeBleTransport {
1106
1114
  const transport = this.getCachedTransport(uuid);
1107
1115
  const runPromise = hdShared.createDeferred();
1108
1116
  runPromise.promise.catch(() => undefined);
1109
- const supersededRunPromise = this.runPromise;
1110
- if (supersededRunPromise) {
1111
- supersededRunPromise.reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleForceCleanRunPromise));
1112
- }
1113
1117
  this.runPromise = runPromise;
1114
1118
  this.runPromiseDeviceId = uuid;
1115
- const releaseOwnershipIfCurrent = () => {
1116
- if (this.runPromise === runPromise) {
1117
- this.runPromise = null;
1118
- this.runPromiseDeviceId = null;
1119
- }
1120
- };
1121
- const isCurrentOwner = () => this.runPromise === runPromise;
1122
1119
  const messages = this._messages;
1123
1120
  const buffers = ProtocolV1.encodeTransportPackets(messages, name, data);
1124
1121
  let timeout;
@@ -1139,9 +1136,6 @@ class ReactNativeBleTransport {
1139
1136
  }
1140
1137
  catch (e) {
1141
1138
  onError(e);
1142
- if (isWedgedWriteError(e)) {
1143
- throw e;
1144
- }
1145
1139
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleWriteCharacteristicError);
1146
1140
  }
1147
1141
  }
@@ -1169,9 +1163,6 @@ class ReactNativeBleTransport {
1169
1163
  }
1170
1164
  catch (e) {
1171
1165
  onError(e);
1172
- if (isWedgedWriteError(e)) {
1173
- throw e;
1174
- }
1175
1166
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleWriteCharacteristicError);
1176
1167
  }
1177
1168
  }
@@ -1182,8 +1173,8 @@ class ReactNativeBleTransport {
1182
1173
  });
1183
1174
  }
1184
1175
  if (name === 'EmmcFileWrite') {
1185
- yield writeChunkedData(buffers, data => this.writeBlePacket(uuid, data, payload => transport.writeWithRetry(payload), isCurrentOwner), e => {
1186
- releaseOwnershipIfCurrent();
1176
+ yield writeChunkedData(buffers, data => transport.writeWithRetry(data), e => {
1177
+ this.runPromise = null;
1187
1178
  Log === null || Log === void 0 ? void 0 : Log.error('writeCharacteristic write error: ', e);
1188
1179
  });
1189
1180
  }
@@ -1199,7 +1190,7 @@ class ReactNativeBleTransport {
1199
1190
  let attempt = 0;
1200
1191
  while (true) {
1201
1192
  try {
1202
- yield this.writeBlePacket(uuid, data, payload => transport.writeWithRetry(payload), isCurrentOwner);
1193
+ yield transport.writeWithRetry(data);
1203
1194
  return;
1204
1195
  }
1205
1196
  catch (error) {
@@ -1218,7 +1209,7 @@ class ReactNativeBleTransport {
1218
1209
  }
1219
1210
  }
1220
1211
  }), e => {
1221
- releaseOwnershipIfCurrent();
1212
+ this.runPromise = null;
1222
1213
  Log === null || Log === void 0 ? void 0 : Log.error('writeCharacteristic write error: ', e);
1223
1214
  });
1224
1215
  }
@@ -1227,16 +1218,16 @@ class ReactNativeBleTransport {
1227
1218
  const outData = o.toString('base64');
1228
1219
  try {
1229
1220
  const shouldUseWriteWithResponse = reactNative.Platform.OS === 'ios' && transport.writeCharacteristic.isWritableWithResponse;
1230
- yield this.writeBlePacket(uuid, outData, payload => shouldUseWriteWithResponse
1231
- ? transport.writeCharacteristic.writeWithResponse(payload)
1232
- : transport.writeCharacteristic.writeWithoutResponse(payload), isCurrentOwner);
1221
+ if (shouldUseWriteWithResponse) {
1222
+ yield transport.writeCharacteristic.writeWithResponse(outData);
1223
+ }
1224
+ else {
1225
+ yield transport.writeCharacteristic.writeWithoutResponse(outData);
1226
+ }
1233
1227
  }
1234
1228
  catch (e) {
1235
1229
  Log === null || Log === void 0 ? void 0 : Log.debug('writeCharacteristic write error: ', e);
1236
- releaseOwnershipIfCurrent();
1237
- if (isWedgedWriteError(e)) {
1238
- throw e;
1239
- }
1230
+ this.runPromise = null;
1240
1231
  if (e.errorCode === reactNativeBlePlx.BleErrorCode.DeviceDisconnected) {
1241
1232
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceNotBonded);
1242
1233
  }
@@ -1276,9 +1267,7 @@ class ReactNativeBleTransport {
1276
1267
  Log === null || Log === void 0 ? void 0 : Log.error('call error: ', e);
1277
1268
  }
1278
1269
  const isProbeTimeout = name === 'GetFeatures' && (options === null || options === void 0 ? void 0 : options.timeoutMs) === PROTOCOL_PROBE_TIMEOUT_MS;
1279
- const isStaleCall = this.runPromise !== runPromise;
1280
1270
  if (!isProbeTimeout &&
1281
- !isStaleCall &&
1282
1271
  (e === null || e === void 0 ? void 0 : e.errorCode) === hdShared.HardwareErrorCode.BleTimeoutError) {
1283
1272
  yield this.disconnect(uuid);
1284
1273
  }
@@ -1349,10 +1338,7 @@ class ReactNativeBleTransport {
1349
1338
  delete transportCache[session];
1350
1339
  }
1351
1340
  this.deviceProtocol.delete(session);
1352
- this.probingProtocols.delete(session);
1353
1341
  this.deviceProtocolHints.delete(session);
1354
- this.sessionProtocols.delete(session);
1355
- this.protocolReprobeFailures.delete(session);
1356
1342
  this.protocolV2Assemblers.delete(session);
1357
1343
  this.resetProtocolV2Frames(session);
1358
1344
  try {
@@ -1373,91 +1359,6 @@ class ReactNativeBleTransport {
1373
1359
  this.runPromise = null;
1374
1360
  this.runPromiseDeviceId = null;
1375
1361
  }
1376
- connectWithTimeout(uuid, connect) {
1377
- return __awaiter(this, void 0, void 0, function* () {
1378
- let timer;
1379
- let timedOut = false;
1380
- const pending = connect();
1381
- pending.catch(() => undefined);
1382
- try {
1383
- const result = yield Promise.race([
1384
- pending,
1385
- new Promise((_, reject) => {
1386
- timer = setTimeout(() => {
1387
- timedOut = true;
1388
- reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleConnectedError, `BLE connect timeout after ${BLE_CONNECT_TIMEOUT_MS}ms for ${uuid}`));
1389
- }, BLE_CONNECT_TIMEOUT_MS);
1390
- }),
1391
- ]);
1392
- return result;
1393
- }
1394
- catch (error) {
1395
- if (timedOut || isNativeOperationTimeoutError(error)) {
1396
- this.abandonStalledConnection(uuid, timedOut ? 'connect-backstop' : 'connect-native');
1397
- }
1398
- throw error;
1399
- }
1400
- finally {
1401
- if (timer)
1402
- clearTimeout(timer);
1403
- }
1404
- });
1405
- }
1406
- resolveCharacteristicsWithTimeout(uuid, device) {
1407
- return __awaiter(this, void 0, void 0, function* () {
1408
- let timer;
1409
- let timedOut = false;
1410
- const pending = this.resolveCharacteristics(device);
1411
- pending.catch(() => undefined);
1412
- try {
1413
- const result = yield Promise.race([
1414
- pending,
1415
- new Promise((_, reject) => {
1416
- timer = setTimeout(() => {
1417
- timedOut = true;
1418
- reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleConnectedError, `BLE GATT setup timeout after ${BLE_GATT_SETUP_TIMEOUT_MS}ms for ${uuid}`));
1419
- }, BLE_GATT_SETUP_TIMEOUT_MS);
1420
- }),
1421
- ]);
1422
- this.connectionSetupTimeoutCounts.delete(uuid);
1423
- return result;
1424
- }
1425
- catch (error) {
1426
- if (timedOut || isNativeOperationTimeoutError(error)) {
1427
- this.abandonStalledConnection(uuid, timedOut ? 'gatt-backstop' : 'gatt-native');
1428
- }
1429
- throw error;
1430
- }
1431
- finally {
1432
- if (timer)
1433
- clearTimeout(timer);
1434
- }
1435
- });
1436
- }
1437
- abandonStalledConnection(uuid, stage) {
1438
- var _a, _b;
1439
- const timeouts = ((_a = this.connectionSetupTimeoutCounts.get(uuid)) !== null && _a !== void 0 ? _a : 0) + 1;
1440
- this.connectionSetupTimeoutCounts.set(uuid, timeouts);
1441
- Log === null || Log === void 0 ? void 0 : Log.error('[ReactNativeBleTransport] BLE setup timed out:', uuid, {
1442
- stage,
1443
- setupTimeoutsSinceSuccess: timeouts,
1444
- });
1445
- (_b = this.blePlxManager) === null || _b === void 0 ? void 0 : _b.cancelDeviceConnection(uuid).catch(() => {
1446
- });
1447
- const stalled = transportCache[uuid];
1448
- if (stalled) {
1449
- delete transportCache[uuid];
1450
- }
1451
- this.deviceProtocol.delete(uuid);
1452
- this.probingProtocols.delete(uuid);
1453
- this.protocolV2Assemblers.delete(uuid);
1454
- this.resetProtocolV2Frames(uuid);
1455
- if (timeouts >= BLE_CONNECT_TIMEOUT_MANAGER_RESET_THRESHOLD) {
1456
- Log === null || Log === void 0 ? void 0 : Log.error('[ReactNativeBleTransport] BLE setup wedged repeatedly, resetting BLE manager');
1457
- this.resetPlxManager();
1458
- this.connectionSetupTimeoutCounts.delete(uuid);
1459
- }
1460
- }
1461
1362
  getCachedTransport(uuid) {
1462
1363
  const transport = transportCache[uuid];
1463
1364
  if (!transport) {
@@ -1465,82 +1366,6 @@ class ReactNativeBleTransport {
1465
1366
  }
1466
1367
  return transport;
1467
1368
  }
1468
- writeBlePacket(uuid, data, write, isCurrentOwner) {
1469
- return __awaiter(this, void 0, void 0, function* () {
1470
- let timer;
1471
- let timedOut = false;
1472
- try {
1473
- yield Promise.race([
1474
- write(data),
1475
- new Promise((_, reject) => {
1476
- timer = setTimeout(() => {
1477
- timedOut = true;
1478
- reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleWriteCharacteristicError, `BLE write timeout after ${BLE_WRITE_PACKET_TIMEOUT_MS}ms`));
1479
- }, BLE_WRITE_PACKET_TIMEOUT_MS);
1480
- }),
1481
- ]);
1482
- this.writeTimeoutCounts.delete(uuid);
1483
- }
1484
- catch (error) {
1485
- if (timedOut) {
1486
- if (isCurrentOwner && !isCurrentOwner()) {
1487
- Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] stale BLE write timed out, link kept:', uuid);
1488
- }
1489
- else {
1490
- this.tearDownWedgedLink(uuid);
1491
- }
1492
- }
1493
- throw error;
1494
- }
1495
- finally {
1496
- if (timer)
1497
- clearTimeout(timer);
1498
- }
1499
- });
1500
- }
1501
- tearDownWedgedLink(uuid) {
1502
- var _a;
1503
- const timeouts = ((_a = this.writeTimeoutCounts.get(uuid)) !== null && _a !== void 0 ? _a : 0) + 1;
1504
- this.writeTimeoutCounts.set(uuid, timeouts);
1505
- Log === null || Log === void 0 ? void 0 : Log.error('[ReactNativeBleTransport] BLE write timed out, tearing down link:', uuid, {
1506
- consecutiveWriteTimeouts: timeouts,
1507
- });
1508
- const wedged = transportCache[uuid];
1509
- this.disconnect(uuid).catch(error => {
1510
- Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] wedged link teardown failed (ignored):', error);
1511
- });
1512
- if (wedged && transportCache[uuid] === wedged) {
1513
- delete transportCache[uuid];
1514
- }
1515
- this.deviceProtocol.delete(uuid);
1516
- this.probingProtocols.delete(uuid);
1517
- this.protocolV2Assemblers.delete(uuid);
1518
- this.resetProtocolV2Frames(uuid);
1519
- if (timeouts >= BLE_WRITE_TIMEOUT_MANAGER_RESET_THRESHOLD) {
1520
- Log === null || Log === void 0 ? void 0 : Log.error('[ReactNativeBleTransport] BLE writes wedged repeatedly, resetting BLE manager');
1521
- this.resetPlxManager();
1522
- this.writeTimeoutCounts.delete(uuid);
1523
- }
1524
- }
1525
- resetPlxManager() {
1526
- const manager = this.blePlxManager;
1527
- this.blePlxManager = undefined;
1528
- Object.keys(transportCache).forEach(key => {
1529
- delete transportCache[key];
1530
- });
1531
- this.deviceProtocol.clear();
1532
- this.probingProtocols.clear();
1533
- this.sessionProtocols.clear();
1534
- this.protocolReprobeFailures.clear();
1535
- this.monitorTokens.clear();
1536
- this.protocolV2Assemblers.clear();
1537
- try {
1538
- manager === null || manager === void 0 ? void 0 : manager.destroy();
1539
- }
1540
- catch (error) {
1541
- Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] BLE manager destroy failed (ignored):', error);
1542
- }
1543
- }
1544
1369
  createProtocolMismatchError(expected) {
1545
1370
  return hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Device protocol mismatch: expected ${expected}, but device did not respond to expected protocol`);
1546
1371
  }
@@ -1548,19 +1373,11 @@ class ReactNativeBleTransport {
1548
1373
  return hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleTimeoutError, 'Unable to detect BLE protocol: device did not respond to Protocol V1 GetFeatures or Protocol V2 Ping');
1549
1374
  }
1550
1375
  clearProbeProtocol(uuid, protocol) {
1551
- if (this.probingProtocols.get(uuid) === protocol) {
1552
- this.probingProtocols.delete(uuid);
1553
- }
1554
1376
  if (this.deviceProtocol.get(uuid) === protocol) {
1555
1377
  this.deviceProtocol.delete(uuid);
1556
1378
  }
1557
1379
  }
1558
- getActiveProtocol(uuid) {
1559
- var _a;
1560
- return (_a = this.deviceProtocol.get(uuid)) !== null && _a !== void 0 ? _a : this.probingProtocols.get(uuid);
1561
- }
1562
1380
  detectProtocol(uuid, expectedProtocol, protocolHint, rebuildTransport) {
1563
- var _a;
1564
1381
  return __awaiter(this, void 0, void 0, function* () {
1565
1382
  if (reactNative.Platform.OS === 'ios' && expectedProtocol) {
1566
1383
  this.deviceProtocol.set(uuid, expectedProtocol);
@@ -1574,7 +1391,6 @@ class ReactNativeBleTransport {
1574
1391
  if (expectedProtocol === 'V1') {
1575
1392
  if (yield this.probeProtocolV1(uuid)) {
1576
1393
  this.deviceProtocol.set(uuid, 'V1');
1577
- this.sessionProtocols.set(uuid, 'V1');
1578
1394
  Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] protocol detected', {
1579
1395
  deviceId: uuid,
1580
1396
  protocol: 'V1',
@@ -1587,7 +1403,6 @@ class ReactNativeBleTransport {
1587
1403
  if (expectedProtocol === 'V2') {
1588
1404
  if (yield this.probeProtocolV2(uuid)) {
1589
1405
  this.deviceProtocol.set(uuid, 'V2');
1590
- this.sessionProtocols.set(uuid, 'V2');
1591
1406
  Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] protocol detected', {
1592
1407
  deviceId: uuid,
1593
1408
  protocol: 'V2',
@@ -1597,13 +1412,7 @@ class ReactNativeBleTransport {
1597
1412
  }
1598
1413
  throw this.createProtocolMismatchError(expectedProtocol);
1599
1414
  }
1600
- const sessionProtocol = this.sessionProtocols.get(uuid);
1601
- const reprobeFailures = (_a = this.protocolReprobeFailures.get(uuid)) !== null && _a !== void 0 ? _a : 0;
1602
- const fullProbeOrder = protocolHint === 'V2' || this.deviceProtocol.get(uuid) === 'V2' ? ['V2', 'V1'] : ['V1', 'V2'];
1603
- const trustSessionProtocol = sessionProtocol !== undefined &&
1604
- !protocolHint &&
1605
- reprobeFailures < PROTOCOL_REPROBE_FALLBACK_ATTEMPTS;
1606
- const probeOrder = trustSessionProtocol ? [sessionProtocol] : fullProbeOrder;
1415
+ const probeOrder = protocolHint === 'V2' || this.deviceProtocol.get(uuid) === 'V2' ? ['V2', 'V1'] : ['V1', 'V2'];
1607
1416
  for (let i = 0; i < probeOrder.length; i += 1) {
1608
1417
  const protocol = probeOrder[i];
1609
1418
  if (i > 0) {
@@ -1618,8 +1427,6 @@ class ReactNativeBleTransport {
1618
1427
  const detected = protocol === 'V1' ? yield this.probeProtocolV1(uuid) : yield this.probeProtocolV2(uuid);
1619
1428
  if (detected) {
1620
1429
  this.deviceProtocol.set(uuid, protocol);
1621
- this.sessionProtocols.set(uuid, protocol);
1622
- this.protocolReprobeFailures.delete(uuid);
1623
1430
  Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] protocol detected', {
1624
1431
  deviceId: uuid,
1625
1432
  protocol,
@@ -1628,14 +1435,7 @@ class ReactNativeBleTransport {
1628
1435
  return protocol;
1629
1436
  }
1630
1437
  }
1631
- if (trustSessionProtocol) {
1632
- this.protocolReprobeFailures.set(uuid, reprobeFailures + 1);
1633
- }
1634
- else {
1635
- this.protocolReprobeFailures.delete(uuid);
1636
- }
1637
1438
  this.deviceProtocol.delete(uuid);
1638
- this.probingProtocols.delete(uuid);
1639
1439
  throw this.createProtocolDetectionError();
1640
1440
  });
1641
1441
  }
@@ -1687,17 +1487,13 @@ class ReactNativeBleTransport {
1687
1487
  return false;
1688
1488
  }
1689
1489
  try {
1690
- this.probingProtocols.set(uuid, 'V1');
1490
+ this.deviceProtocol.set(uuid, 'V1');
1691
1491
  yield this.callProtocolV1(uuid, 'GetFeatures', {}, { timeoutMs: PROTOCOL_PROBE_TIMEOUT_MS });
1692
- this.probingProtocols.delete(uuid);
1693
1492
  return true;
1694
1493
  }
1695
1494
  catch (error) {
1696
1495
  this.clearProbeProtocol(uuid, 'V1');
1697
1496
  Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V1 GetFeatures probe failed:', error);
1698
- if (isWedgedWriteError(error)) {
1699
- throw error;
1700
- }
1701
1497
  return false;
1702
1498
  }
1703
1499
  });
@@ -1708,7 +1504,7 @@ class ReactNativeBleTransport {
1708
1504
  if (!this._messages || !this._messagesV2) {
1709
1505
  return false;
1710
1506
  }
1711
- this.probingProtocols.set(uuid, 'V2');
1507
+ this.deviceProtocol.set(uuid, 'V2');
1712
1508
  (_a = this.protocolV2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
1713
1509
  const detected = yield transport.probeProtocolV2({
1714
1510
  call: (name, data, options) => this.callProtocolV2(uuid, name, data, options),
@@ -1724,9 +1520,6 @@ class ReactNativeBleTransport {
1724
1520
  if (!detected) {
1725
1521
  this.clearProbeProtocol(uuid, 'V2');
1726
1522
  }
1727
- else {
1728
- this.probingProtocols.delete(uuid);
1729
- }
1730
1523
  return detected;
1731
1524
  });
1732
1525
  }
@@ -1798,10 +1591,14 @@ class ReactNativeBleTransport {
1798
1591
  }
1799
1592
  });
1800
1593
  }
1801
- writeProtocolV2Packet(uuid, transport, base64, context, assertCurrentGeneration) {
1594
+ writeProtocolV2Packet(transport, base64, context, assertCurrentGeneration) {
1802
1595
  return __awaiter(this, void 0, void 0, function* () {
1803
- const shouldUseWriteWithResponse = transport.writeCharacteristic.isWritableWithResponse &&
1804
- (context.writeWithResponse === true || (reactNative.Platform.OS === 'ios' && !context.highVolume));
1596
+ const shouldUseWriteWithResponse = shouldWriteProtocolV2WithResponse({
1597
+ platform: reactNative.Platform.OS,
1598
+ highVolume: context.highVolume,
1599
+ requestedWithResponse: context.writeWithResponse,
1600
+ characteristic: transport.writeCharacteristic,
1601
+ });
1805
1602
  let attempt = 0;
1806
1603
  for (;;) {
1807
1604
  assertCurrentGeneration();
@@ -1809,17 +1606,12 @@ class ReactNativeBleTransport {
1809
1606
  throw new Error(`Protocol V2 BLE write aborted for ${context.messageName}`);
1810
1607
  }
1811
1608
  try {
1812
- yield this.writeBlePacket(uuid, base64, payload => shouldUseWriteWithResponse
1813
- ? transport.writeCharacteristic.writeWithResponse(payload)
1814
- : transport.writeCharacteristic.writeWithoutResponse(payload), () => {
1815
- try {
1816
- assertCurrentGeneration();
1817
- return !context.signal.aborted;
1818
- }
1819
- catch (_a) {
1820
- return false;
1821
- }
1822
- });
1609
+ if (shouldUseWriteWithResponse) {
1610
+ yield transport.writeCharacteristic.writeWithResponse(base64);
1611
+ }
1612
+ else {
1613
+ yield transport.writeCharacteristic.writeWithoutResponse(base64);
1614
+ }
1823
1615
  assertCurrentGeneration();
1824
1616
  return;
1825
1617
  }
@@ -1840,34 +1632,28 @@ class ReactNativeBleTransport {
1840
1632
  }
1841
1633
  });
1842
1634
  }
1843
- writeProtocolV2Frame(uuid, transport$1, frame, context, assertCurrentGeneration) {
1635
+ writeProtocolV2Frame(transport$1, frame, context, assertCurrentGeneration) {
1844
1636
  return __awaiter(this, void 0, void 0, function* () {
1845
1637
  const tuning = getProtocolV2BleTuning();
1846
1638
  const packetCapacity = resolveProtocolV2PacketCapacity({
1847
1639
  platform: reactNative.Platform.OS,
1848
1640
  iosPacketLength: tuning.iosPacketLength,
1849
1641
  androidPacketLength: tuning.androidPacketLength,
1850
- mtu: reactNative.Platform.OS === 'android' ? transport$1.mtuSize : undefined,
1642
+ mtu: transport$1.mtuSize,
1851
1643
  });
1852
- const initialDelayMs = reactNative.Platform.OS === 'ios' && !context.highVolume && frame.length <= packetCapacity
1853
- ? IOS_PROTOCOL_V2_CONTROL_WRITE_DELAY_MS
1854
- : 0;
1855
1644
  yield transport.writeProtocolV2BleFrame({
1856
1645
  frame,
1857
1646
  packetCapacity,
1858
1647
  assertActive: assertCurrentGeneration,
1859
1648
  signal: context.signal,
1860
1649
  abortMessage: `Protocol V2 BLE write aborted for ${context.messageName}`,
1861
- initialDelayMs,
1862
- burstSize: FIRMWARE_UPLOAD_WRITE_BURST_SIZE,
1863
- burstPauseMs: FIRMWARE_UPLOAD_WRITE_PAUSE_MS,
1864
- flushDelayMs: FIRMWARE_UPLOAD_WRITE_FLUSH_DELAY_MS,
1865
1650
  wait: delay,
1866
- writePacket: packet => this.writeProtocolV2Packet(uuid, transport$1, buffer.Buffer.from(packet).toString('base64'), context, assertCurrentGeneration),
1651
+ writePacket: packet => this.writeProtocolV2Packet(transport$1, buffer.Buffer.from(packet).toString('base64'), context, assertCurrentGeneration),
1867
1652
  });
1868
1653
  });
1869
1654
  }
1870
1655
  callProtocolV2(uuid, name, data, options) {
1656
+ var _a;
1871
1657
  return __awaiter(this, void 0, void 0, function* () {
1872
1658
  if (!this._messages || !this._messagesV2) {
1873
1659
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.TransportNotConfigured);
@@ -1876,11 +1662,35 @@ class ReactNativeBleTransport {
1876
1662
  const highVolumeWrite = transport.LogBlockCommand.has(name);
1877
1663
  if (highVolumeWrite) {
1878
1664
  const tuning = getProtocolV2BleTuning();
1879
- Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V2 high-volume write configured', {
1880
- name,
1881
- writeMode: (options === null || options === void 0 ? void 0 : options.writeWithResponse) ? 'withResponse' : 'withoutResponse',
1882
- packetCapacity: reactNative.Platform.OS === 'ios' ? tuning.iosPacketLength : tuning.androidPacketLength,
1665
+ const currentTransport = this.getCachedTransport(uuid);
1666
+ const writeWithResponse = shouldWriteProtocolV2WithResponse({
1667
+ platform: reactNative.Platform.OS,
1668
+ highVolume: true,
1669
+ requestedWithResponse: options === null || options === void 0 ? void 0 : options.writeWithResponse,
1670
+ characteristic: currentTransport.writeCharacteristic,
1883
1671
  });
1672
+ const packetCapacity = resolveProtocolV2PacketCapacity({
1673
+ platform: reactNative.Platform.OS,
1674
+ iosPacketLength: tuning.iosPacketLength,
1675
+ androidPacketLength: tuning.androidPacketLength,
1676
+ mtu: currentTransport.mtuSize,
1677
+ });
1678
+ const writeMode = writeWithResponse ? 'withResponse' : 'withoutResponse';
1679
+ const logSignature = `${name}:${writeMode}:${String(currentTransport.mtuSize)}:${packetCapacity}`;
1680
+ const loggedSignatures = (_a = this.protocolV2HighVolumeLogSignatures.get(uuid)) !== null && _a !== void 0 ? _a : new Set();
1681
+ if (!loggedSignatures.has(logSignature)) {
1682
+ loggedSignatures.add(logSignature);
1683
+ this.protocolV2HighVolumeLogSignatures.set(uuid, loggedSignatures);
1684
+ Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V2 high-volume write configured', {
1685
+ name,
1686
+ writeMode,
1687
+ reportedMtu: currentTransport.mtuSize,
1688
+ packetCapacity,
1689
+ });
1690
+ }
1691
+ }
1692
+ if (highVolumeWrite) {
1693
+ yield this.enableAndroidHighConnectionPriority(uuid);
1884
1694
  }
1885
1695
  try {
1886
1696
  return yield this.protocolV2Links.call(uuid, () => this.createProtocolV2Adapter(uuid), name, data, callOptions);
@@ -1889,6 +1699,71 @@ class ReactNativeBleTransport {
1889
1699
  Log === null || Log === void 0 ? void 0 : Log.error('[ReactNativeBleTransport] Protocol V2 call error:', e);
1890
1700
  throw e;
1891
1701
  }
1702
+ finally {
1703
+ if (highVolumeWrite) {
1704
+ this.scheduleAndroidBalancedConnectionPriority(uuid);
1705
+ }
1706
+ }
1707
+ });
1708
+ }
1709
+ clearAndroidPriorityResetTimer(uuid) {
1710
+ const timerId = this.androidPriorityResetTimers.get(uuid);
1711
+ if (timerId !== undefined) {
1712
+ clearTimeout(timerId);
1713
+ this.androidPriorityResetTimers.delete(uuid);
1714
+ }
1715
+ }
1716
+ enableAndroidHighConnectionPriority(uuid) {
1717
+ return __awaiter(this, void 0, void 0, function* () {
1718
+ if (reactNative.Platform.OS !== 'android')
1719
+ return;
1720
+ this.clearAndroidPriorityResetTimer(uuid);
1721
+ if (this.androidHighPriorityDevices.has(uuid))
1722
+ return;
1723
+ const transport = transportCache[uuid];
1724
+ if (!transport)
1725
+ return;
1726
+ try {
1727
+ transport.device = yield transport.device.requestConnectionPriority(reactNativeBlePlx.ConnectionPriority.High);
1728
+ this.androidHighPriorityDevices.add(uuid);
1729
+ Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Android BLE connection priority changed', {
1730
+ priority: 'high',
1731
+ });
1732
+ }
1733
+ catch (error) {
1734
+ Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Android BLE high priority request failed', {
1735
+ error: error instanceof Error ? error.message : String(error),
1736
+ });
1737
+ }
1738
+ });
1739
+ }
1740
+ scheduleAndroidBalancedConnectionPriority(uuid) {
1741
+ if (reactNative.Platform.OS !== 'android' || !this.androidHighPriorityDevices.has(uuid))
1742
+ return;
1743
+ this.clearAndroidPriorityResetTimer(uuid);
1744
+ const timerId = setTimeout(() => {
1745
+ this.androidPriorityResetTimers.delete(uuid);
1746
+ this.restoreAndroidConnectionPriority(uuid, transportCache[uuid]).catch(error => Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Android BLE priority restore failed', error));
1747
+ }, ANDROID_HIGH_PRIORITY_IDLE_MS);
1748
+ this.androidPriorityResetTimers.set(uuid, timerId);
1749
+ }
1750
+ restoreAndroidConnectionPriority(uuid, transport) {
1751
+ return __awaiter(this, void 0, void 0, function* () {
1752
+ this.clearAndroidPriorityResetTimer(uuid);
1753
+ if (reactNative.Platform.OS !== 'android' || !this.androidHighPriorityDevices.delete(uuid) || !transport) {
1754
+ return;
1755
+ }
1756
+ try {
1757
+ transport.device = yield transport.device.requestConnectionPriority(reactNativeBlePlx.ConnectionPriority.Balanced);
1758
+ Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Android BLE connection priority changed', {
1759
+ priority: 'balanced',
1760
+ });
1761
+ }
1762
+ catch (error) {
1763
+ Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Android BLE balanced priority request failed', {
1764
+ error: error instanceof Error ? error.message : String(error),
1765
+ });
1766
+ }
1892
1767
  });
1893
1768
  }
1894
1769
  createProtocolV2Adapter(uuid) {
@@ -1912,7 +1787,7 @@ class ReactNativeBleTransport {
1912
1787
  writeFrame: (frame, context) => __awaiter(this, void 0, void 0, function* () {
1913
1788
  assertCurrentGeneration();
1914
1789
  const currentTransport = this.getCachedTransport(uuid);
1915
- yield this.writeProtocolV2Frame(uuid, currentTransport, frame, context, assertCurrentGeneration);
1790
+ yield this.writeProtocolV2Frame(currentTransport, frame, context, assertCurrentGeneration);
1916
1791
  }),
1917
1792
  readFrame: () => __awaiter(this, void 0, void 0, function* () {
1918
1793
  assertCurrentGeneration();
@@ -1933,16 +1808,10 @@ class ReactNativeBleTransport {
1933
1808
  };
1934
1809
  }
1935
1810
  getProtocolType(path) {
1936
- return this.getActiveProtocol(path);
1811
+ return this.deviceProtocol.get(path);
1937
1812
  }
1938
1813
  }
1939
1814
 
1940
- exports.BLE_CONNECT_TIMEOUT_MANAGER_RESET_THRESHOLD = BLE_CONNECT_TIMEOUT_MANAGER_RESET_THRESHOLD;
1941
- exports.BLE_CONNECT_TIMEOUT_MS = BLE_CONNECT_TIMEOUT_MS;
1942
- exports.BLE_GATT_SETUP_TIMEOUT_MS = BLE_GATT_SETUP_TIMEOUT_MS;
1943
- exports.BLE_WRITE_PACKET_TIMEOUT_MS = BLE_WRITE_PACKET_TIMEOUT_MS;
1944
- exports.BLE_WRITE_TIMEOUT_MANAGER_RESET_THRESHOLD = BLE_WRITE_TIMEOUT_MANAGER_RESET_THRESHOLD;
1945
- exports.PROTOCOL_REPROBE_FALLBACK_ATTEMPTS = PROTOCOL_REPROBE_FALLBACK_ATTEMPTS;
1946
1815
  exports.configureProtocolV2BleTuning = configureProtocolV2BleTuning;
1947
1816
  exports["default"] = ReactNativeBleTransport;
1948
1817
  exports.getFirmwareUploadWriteRetryType = getFirmwareUploadWriteRetryType;