@onekeyfe/hd-transport-react-native 1.2.0-alpha.66 → 1.2.0-alpha.67
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/BleTransport.d.ts.map +1 -1
- package/dist/index.d.ts +79 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +308 -109
- package/jest.config.js +5 -0
- package/package.json +5 -5
- package/src/BleTransport.ts +0 -6
- package/src/__tests__/BleTransport.test.ts +2 -54
- package/src/__tests__/connectTimeout.test.ts +281 -0
- package/src/__tests__/protocolReprobe.test.ts +132 -0
- package/src/__tests__/protocolV1SchemaFixture.ts +39 -0
- package/src/__tests__/protocolV2Link.test.ts +48 -281
- package/src/__tests__/staleCallTimeout.test.ts +210 -0
- package/src/__tests__/writePacketTimeout.test.ts +305 -0
- package/src/index.ts +451 -112
- package/src/__tests__/enumerate.test.ts +0 -132
package/dist/index.js
CHANGED
|
@@ -210,10 +210,6 @@ class BleTransport {
|
|
|
210
210
|
}
|
|
211
211
|
writeWithRetry(data) {
|
|
212
212
|
return __awaiter(this, void 0, void 0, function* () {
|
|
213
|
-
if (reactNative.Platform.OS === 'ios' && this.writeCharacteristic.isWritableWithResponse) {
|
|
214
|
-
yield this.writeCharacteristic.writeWithResponse(data);
|
|
215
|
-
return;
|
|
216
|
-
}
|
|
217
213
|
yield this.writeCharacteristic.writeWithoutResponse(data);
|
|
218
214
|
});
|
|
219
215
|
}
|
|
@@ -226,36 +222,9 @@ const FIRMWARE_UPLOAD_WRITE_BURST_SIZE = reactNative.Platform.OS === 'ios' ? 4 :
|
|
|
226
222
|
const FIRMWARE_UPLOAD_WRITE_PAUSE_MS = reactNative.Platform.OS === 'ios' ? 8 : 10;
|
|
227
223
|
const FIRMWARE_UPLOAD_WRITE_FLUSH_DELAY_MS = reactNative.Platform.OS === 'ios' ? 24 : 30;
|
|
228
224
|
const FIRMWARE_UPLOAD_WRITE_MAX_RETRIES = 8;
|
|
229
|
-
const IOS_PROTOCOL_V2_CONTROL_WRITE_DELAY_MS = 5;
|
|
230
225
|
const ANDROID_FIRMWARE_UPLOAD_PACKET_LENGTH = 192;
|
|
231
226
|
const FIRMWARE_UPLOAD_WRITE_PACKET_CAPACITY = reactNative.Platform.OS === 'ios' ? IOS_PACKET_LENGTH : ANDROID_FIRMWARE_UPLOAD_PACKET_LENGTH;
|
|
232
227
|
const ANDROID_GATT_CONGESTED_STATUS = 143;
|
|
233
|
-
const isAsciiWhitespace = (code) => code === 0x09 ||
|
|
234
|
-
code === 0x0a ||
|
|
235
|
-
code === 0x0b ||
|
|
236
|
-
code === 0x0c ||
|
|
237
|
-
code === 0x0d ||
|
|
238
|
-
code === 0x20;
|
|
239
|
-
const hasGattCongestedStatus = (text) => {
|
|
240
|
-
let searchFrom = 0;
|
|
241
|
-
while (searchFrom < text.length) {
|
|
242
|
-
const statusIndex = text.indexOf('status', searchFrom);
|
|
243
|
-
if (statusIndex < 0)
|
|
244
|
-
return false;
|
|
245
|
-
let cursor = statusIndex + 'status'.length;
|
|
246
|
-
while (cursor < text.length && isAsciiWhitespace(text.charCodeAt(cursor)))
|
|
247
|
-
cursor += 1;
|
|
248
|
-
if (text[cursor] === ':' || text[cursor] === '=') {
|
|
249
|
-
cursor += 1;
|
|
250
|
-
while (cursor < text.length && isAsciiWhitespace(text.charCodeAt(cursor)))
|
|
251
|
-
cursor += 1;
|
|
252
|
-
}
|
|
253
|
-
if (text.startsWith(String(ANDROID_GATT_CONGESTED_STATUS), cursor))
|
|
254
|
-
return true;
|
|
255
|
-
searchFrom = statusIndex + 'status'.length;
|
|
256
|
-
}
|
|
257
|
-
return false;
|
|
258
|
-
};
|
|
259
228
|
const delay = (ms) => new Promise(resolve => {
|
|
260
229
|
setTimeout(resolve, ms);
|
|
261
230
|
});
|
|
@@ -270,11 +239,17 @@ const getFirmwareUploadWriteRetryType = (error) => {
|
|
|
270
239
|
const text = [bleWriteError.reason, bleWriteError.message, bleWriteError.name]
|
|
271
240
|
.filter(value => typeof value === 'string')
|
|
272
241
|
.join(' ');
|
|
273
|
-
return
|
|
242
|
+
return /GATT_CONGESTED|status\s*[:=]?\s*143/.test(text) ? 'congested' : null;
|
|
274
243
|
};
|
|
275
244
|
const resolveFirmwareUploadRetryDelay = (attempt, baseDelayMs = 200, maxDelayMs = 1200) => Math.min(baseDelayMs * Math.pow(2, attempt), maxDelayMs);
|
|
276
245
|
const PROTOCOL_PROBE_TIMEOUT_MS = 1000;
|
|
277
246
|
const PROTOCOL_V2_PROBE_TIMEOUT_MS = 10000;
|
|
247
|
+
const BLE_WRITE_PACKET_TIMEOUT_MS = 10000;
|
|
248
|
+
const WEDGED_WRITE_MESSAGE = 'BLE write timeout after';
|
|
249
|
+
const isWedgedWriteError = (error) => (error === null || error === void 0 ? void 0 : error.errorCode) === hdShared.HardwareErrorCode.BleWriteCharacteristicError &&
|
|
250
|
+
typeof (error === null || error === void 0 ? void 0 : error.message) === 'string' &&
|
|
251
|
+
error.message.startsWith(WEDGED_WRITE_MESSAGE);
|
|
252
|
+
const BLE_WRITE_TIMEOUT_MANAGER_RESET_THRESHOLD = 2;
|
|
278
253
|
const DEVICE_SCAN_TIMEOUT_MS = 3000;
|
|
279
254
|
const IOS_NOTIFY_READY_DELAY_MS = 150;
|
|
280
255
|
const ANDROID_NOTIFY_READY_DELAY_MS = 300;
|
|
@@ -310,11 +285,24 @@ function getDeviceDisplayName(device) {
|
|
|
310
285
|
return (device === null || device === void 0 ? void 0 : device.name) || (device === null || device === void 0 ? void 0 : device.localName) || null;
|
|
311
286
|
}
|
|
312
287
|
const ANDROID_REQUEST_MTU = 256;
|
|
288
|
+
const BLE_NATIVE_CONNECT_TIMEOUT_MS = 3000;
|
|
313
289
|
const connectOptions = {
|
|
314
290
|
requestMTU: ANDROID_REQUEST_MTU,
|
|
315
|
-
timeout:
|
|
291
|
+
timeout: BLE_NATIVE_CONNECT_TIMEOUT_MS,
|
|
316
292
|
refreshGatt: 'OnConnected',
|
|
317
293
|
};
|
|
294
|
+
const fallbackConnectOptions = {
|
|
295
|
+
timeout: BLE_NATIVE_CONNECT_TIMEOUT_MS,
|
|
296
|
+
};
|
|
297
|
+
const BLE_CONNECT_TIMEOUT_MS = BLE_NATIVE_CONNECT_TIMEOUT_MS * 2 + 2000;
|
|
298
|
+
const BLE_GATT_SETUP_TIMEOUT_MS = 10000;
|
|
299
|
+
const PROTOCOL_REPROBE_FALLBACK_ATTEMPTS = 3;
|
|
300
|
+
const BLE_CONNECT_TIMEOUT_MANAGER_RESET_THRESHOLD = 2;
|
|
301
|
+
const CONNECT_TIMEOUT_MESSAGE = 'BLE connect timeout after';
|
|
302
|
+
const isConnectTimeoutError = (error) => (error === null || error === void 0 ? void 0 : error.errorCode) === hdShared.HardwareErrorCode.BleConnectedError &&
|
|
303
|
+
typeof (error === null || error === void 0 ? void 0 : error.message) === 'string' &&
|
|
304
|
+
error.message.startsWith(CONNECT_TIMEOUT_MESSAGE);
|
|
305
|
+
const isNativeOperationTimeoutError = (error) => (error === null || error === void 0 ? void 0 : error.errorCode) === reactNativeBlePlx.BleErrorCode.OperationTimedOut;
|
|
318
306
|
const tryToGetConfiguration = (device) => {
|
|
319
307
|
if (!device || !device.serviceUUIDs)
|
|
320
308
|
return null;
|
|
@@ -372,7 +360,12 @@ class ReactNativeBleTransport {
|
|
|
372
360
|
this.runPromiseDeviceId = null;
|
|
373
361
|
this.firmwareUploadWriteRecoveryIds = new Set();
|
|
374
362
|
this.deviceProtocol = new Map();
|
|
363
|
+
this.probingProtocols = new Map();
|
|
364
|
+
this.writeTimeoutCounts = new Map();
|
|
365
|
+
this.connectionSetupTimeoutCounts = new Map();
|
|
375
366
|
this.deviceProtocolHints = new Map();
|
|
367
|
+
this.sessionProtocols = new Map();
|
|
368
|
+
this.protocolReprobeFailures = new Map();
|
|
376
369
|
this.protocolV2Assemblers = new Map();
|
|
377
370
|
this.protocolV2FrameQueues = new Map();
|
|
378
371
|
this.protocolV2FramePromises = new Map();
|
|
@@ -564,19 +557,19 @@ class ReactNativeBleTransport {
|
|
|
564
557
|
const isConnected = yield device.isConnected().catch(() => false);
|
|
565
558
|
if (!isConnected) {
|
|
566
559
|
try {
|
|
567
|
-
device = yield device.connect(connectOptions);
|
|
560
|
+
device = yield this.connectWithTimeout(uuid, () => device.connect(connectOptions));
|
|
568
561
|
}
|
|
569
562
|
catch (e) {
|
|
570
563
|
if (e.errorCode === reactNativeBlePlx.BleErrorCode.DeviceMTUChangeFailed ||
|
|
571
564
|
e.errorCode === reactNativeBlePlx.BleErrorCode.OperationCancelled) {
|
|
572
|
-
device = yield device.connect();
|
|
565
|
+
device = yield this.connectWithTimeout(uuid, () => device.connect());
|
|
573
566
|
}
|
|
574
567
|
else if (e.errorCode !== reactNativeBlePlx.BleErrorCode.DeviceAlreadyConnected) {
|
|
575
568
|
throw e;
|
|
576
569
|
}
|
|
577
570
|
}
|
|
578
571
|
}
|
|
579
|
-
const { writeCharacteristic, notifyCharacteristic } = yield this.
|
|
572
|
+
const { writeCharacteristic, notifyCharacteristic } = yield this.resolveCharacteristicsWithTimeout(uuid, device);
|
|
580
573
|
transport.device = device;
|
|
581
574
|
transport.writeCharacteristic = writeCharacteristic;
|
|
582
575
|
transport.notifyCharacteristic = notifyCharacteristic;
|
|
@@ -645,17 +638,12 @@ class ReactNativeBleTransport {
|
|
|
645
638
|
return;
|
|
646
639
|
}
|
|
647
640
|
const displayName = getDeviceDisplayName(device);
|
|
648
|
-
const
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
id: device === null || device === void 0 ? void 0 : device.id,
|
|
655
|
-
name: device === null || device === void 0 ? void 0 : device.name,
|
|
656
|
-
localName: device === null || device === void 0 ? void 0 : device.localName,
|
|
657
|
-
serviceUuids: device === null || device === void 0 ? void 0 : device.serviceUUIDs,
|
|
658
|
-
});
|
|
641
|
+
const isOneKey = hdShared.isOnekeyBluetoothDevice({
|
|
642
|
+
id: device === null || device === void 0 ? void 0 : device.id,
|
|
643
|
+
name: device === null || device === void 0 ? void 0 : device.name,
|
|
644
|
+
localName: device === null || device === void 0 ? void 0 : device.localName,
|
|
645
|
+
serviceUuids: device === null || device === void 0 ? void 0 : device.serviceUUIDs,
|
|
646
|
+
});
|
|
659
647
|
if (isOneKey) {
|
|
660
648
|
addDevice(device);
|
|
661
649
|
}
|
|
@@ -673,15 +661,12 @@ class ReactNativeBleTransport {
|
|
|
673
661
|
const localName = 'localName' in device && typeof device.localName === 'string'
|
|
674
662
|
? device.localName
|
|
675
663
|
: null;
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
localName,
|
|
683
|
-
serviceUuids: device.serviceUUIDs,
|
|
684
|
-
})) {
|
|
664
|
+
if (hdShared.isOnekeyBluetoothDevice({
|
|
665
|
+
id: device.id,
|
|
666
|
+
name: device.name,
|
|
667
|
+
localName,
|
|
668
|
+
serviceUuids: device.serviceUUIDs,
|
|
669
|
+
})) {
|
|
685
670
|
Log === null || Log === void 0 ? void 0 : Log.debug('search connected peripheral: ', device.id);
|
|
686
671
|
addDevice(device);
|
|
687
672
|
}
|
|
@@ -713,7 +698,7 @@ class ReactNativeBleTransport {
|
|
|
713
698
|
}
|
|
714
699
|
installTransportForAcquire(uuid, device, characteristics) {
|
|
715
700
|
return __awaiter(this, void 0, void 0, function* () {
|
|
716
|
-
const { writeCharacteristic, notifyCharacteristic } = characteristics !== null && characteristics !== void 0 ? characteristics : (yield this.
|
|
701
|
+
const { writeCharacteristic, notifyCharacteristic } = characteristics !== null && characteristics !== void 0 ? characteristics : (yield this.resolveCharacteristicsWithTimeout(uuid, device));
|
|
717
702
|
const transport$1 = new BleTransport(device, writeCharacteristic, notifyCharacteristic);
|
|
718
703
|
if (reactNative.Platform.OS === 'android') {
|
|
719
704
|
transport$1.mtuSize = typeof device.mtu === 'number' ? device.mtu : transport$1.mtuSize;
|
|
@@ -796,14 +781,17 @@ class ReactNativeBleTransport {
|
|
|
796
781
|
if (!device) {
|
|
797
782
|
Log === null || Log === void 0 ? void 0 : Log.debug('try to connect to device: ', uuid);
|
|
798
783
|
try {
|
|
799
|
-
device = yield blePlxManager.connectToDevice(uuid, connectOptions);
|
|
784
|
+
device = yield this.connectWithTimeout(uuid, () => blePlxManager.connectToDevice(uuid, connectOptions));
|
|
800
785
|
}
|
|
801
786
|
catch (e) {
|
|
802
787
|
Log === null || Log === void 0 ? void 0 : Log.debug('try to connect to device has error: ', e);
|
|
788
|
+
if (isConnectTimeoutError(e)) {
|
|
789
|
+
throw e;
|
|
790
|
+
}
|
|
803
791
|
if (e.errorCode === reactNativeBlePlx.BleErrorCode.DeviceMTUChangeFailed ||
|
|
804
792
|
e.errorCode === reactNativeBlePlx.BleErrorCode.OperationCancelled) {
|
|
805
793
|
Log === null || Log === void 0 ? void 0 : Log.debug('first try to reconnect without params');
|
|
806
|
-
device = yield blePlxManager.connectToDevice(uuid);
|
|
794
|
+
device = yield this.connectWithTimeout(uuid, () => blePlxManager.connectToDevice(uuid, fallbackConnectOptions));
|
|
807
795
|
}
|
|
808
796
|
else if (e.errorCode === reactNativeBlePlx.BleErrorCode.DeviceAlreadyConnected) {
|
|
809
797
|
Log === null || Log === void 0 ? void 0 : Log.debug('device already connected');
|
|
@@ -819,23 +807,27 @@ class ReactNativeBleTransport {
|
|
|
819
807
|
}
|
|
820
808
|
if (!(yield device.isConnected())) {
|
|
821
809
|
Log === null || Log === void 0 ? void 0 : Log.debug('not connected, try to connect to device: ', uuid);
|
|
810
|
+
const disconnectedDevice = device;
|
|
822
811
|
try {
|
|
823
|
-
device = yield
|
|
812
|
+
device = yield this.connectWithTimeout(uuid, () => disconnectedDevice.connect(connectOptions));
|
|
824
813
|
}
|
|
825
814
|
catch (e) {
|
|
826
815
|
Log === null || Log === void 0 ? void 0 : Log.debug('not connected, try to connect to device has error: ', e);
|
|
816
|
+
if (isConnectTimeoutError(e)) {
|
|
817
|
+
throw e;
|
|
818
|
+
}
|
|
827
819
|
if (e.errorCode === reactNativeBlePlx.BleErrorCode.DeviceMTUChangeFailed ||
|
|
828
820
|
e.errorCode === reactNativeBlePlx.BleErrorCode.OperationCancelled) {
|
|
829
821
|
Log === null || Log === void 0 ? void 0 : Log.debug('second try to reconnect without params');
|
|
830
822
|
try {
|
|
831
|
-
device = yield
|
|
823
|
+
device = yield this.connectWithTimeout(uuid, () => disconnectedDevice.connect(fallbackConnectOptions));
|
|
832
824
|
}
|
|
833
825
|
catch (e) {
|
|
834
826
|
Log === null || Log === void 0 ? void 0 : Log.debug('last try to reconnect error: ', e);
|
|
835
827
|
if (e.errorCode === reactNativeBlePlx.BleErrorCode.OperationCancelled) {
|
|
836
828
|
Log === null || Log === void 0 ? void 0 : Log.debug('last try to reconnect');
|
|
837
|
-
yield
|
|
838
|
-
device = yield
|
|
829
|
+
yield disconnectedDevice.cancelConnection();
|
|
830
|
+
device = yield this.connectWithTimeout(uuid, () => disconnectedDevice.connect(fallbackConnectOptions));
|
|
839
831
|
}
|
|
840
832
|
}
|
|
841
833
|
}
|
|
@@ -846,7 +838,7 @@ class ReactNativeBleTransport {
|
|
|
846
838
|
}
|
|
847
839
|
device = yield requestAndroidMtu(device);
|
|
848
840
|
const acquiredDevice = device;
|
|
849
|
-
const { writeCharacteristic, notifyCharacteristic } = yield this.
|
|
841
|
+
const { writeCharacteristic, notifyCharacteristic } = yield this.resolveCharacteristicsWithTimeout(uuid, acquiredDevice);
|
|
850
842
|
const protocolHint = expectedProtocol
|
|
851
843
|
? undefined
|
|
852
844
|
: (_b = (_a = input.protocolHint) !== null && _a !== void 0 ? _a : this.deviceProtocolHints.get(uuid)) !== null && _b !== void 0 ? _b : inferProtocolHintFromDeviceName(getDeviceDisplayName(acquiredDevice));
|
|
@@ -891,7 +883,7 @@ class ReactNativeBleTransport {
|
|
|
891
883
|
Log === null || Log === void 0 ? void 0 : Log.debug('monitor error ignored for stale transport: ', uuid, notifyTransactionId);
|
|
892
884
|
return;
|
|
893
885
|
}
|
|
894
|
-
if (this.
|
|
886
|
+
if (this.getActiveProtocol(uuid) === 'V2') {
|
|
895
887
|
let errorCode = hdShared.HardwareErrorCode.BleCharacteristicNotifyError;
|
|
896
888
|
if ((_a = error.reason) === null || _a === void 0 ? void 0 : _a.includes('The connection has timed out unexpectedly')) {
|
|
897
889
|
errorCode = hdShared.HardwareErrorCode.BleTimeoutError;
|
|
@@ -942,7 +934,7 @@ class ReactNativeBleTransport {
|
|
|
942
934
|
}
|
|
943
935
|
try {
|
|
944
936
|
const data = buffer.Buffer.from(c.value, 'base64');
|
|
945
|
-
const protocol = this.
|
|
937
|
+
const protocol = this.getActiveProtocol(uuid);
|
|
946
938
|
if (!protocol) {
|
|
947
939
|
Log === null || Log === void 0 ? void 0 : Log.debug('monitor data ignored before protocol detection: ', uuid);
|
|
948
940
|
return;
|
|
@@ -970,7 +962,7 @@ class ReactNativeBleTransport {
|
|
|
970
962
|
catch (error) {
|
|
971
963
|
Log === null || Log === void 0 ? void 0 : Log.debug('monitor data error: ', error);
|
|
972
964
|
const notifyError = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleWriteCharacteristicError);
|
|
973
|
-
if (this.
|
|
965
|
+
if (this.getActiveProtocol(uuid) === 'V2') {
|
|
974
966
|
this.rejectProtocolV2Frames(uuid, notifyError);
|
|
975
967
|
}
|
|
976
968
|
else if (this.runPromiseDeviceId === uuid) {
|
|
@@ -1026,6 +1018,7 @@ class ReactNativeBleTransport {
|
|
|
1026
1018
|
delete transportCache[uuid];
|
|
1027
1019
|
}
|
|
1028
1020
|
this.deviceProtocol.delete(uuid);
|
|
1021
|
+
this.probingProtocols.delete(uuid);
|
|
1029
1022
|
(_f = this.protocolV2Assemblers.get(uuid)) === null || _f === void 0 ? void 0 : _f.reset();
|
|
1030
1023
|
this.protocolV2Assemblers.delete(uuid);
|
|
1031
1024
|
this.resetProtocolV2Frames(uuid);
|
|
@@ -1074,8 +1067,19 @@ class ReactNativeBleTransport {
|
|
|
1074
1067
|
const transport = this.getCachedTransport(uuid);
|
|
1075
1068
|
const runPromise = hdShared.createDeferred();
|
|
1076
1069
|
runPromise.promise.catch(() => undefined);
|
|
1070
|
+
const supersededRunPromise = this.runPromise;
|
|
1071
|
+
if (supersededRunPromise) {
|
|
1072
|
+
supersededRunPromise.reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleForceCleanRunPromise));
|
|
1073
|
+
}
|
|
1077
1074
|
this.runPromise = runPromise;
|
|
1078
1075
|
this.runPromiseDeviceId = uuid;
|
|
1076
|
+
const releaseOwnershipIfCurrent = () => {
|
|
1077
|
+
if (this.runPromise === runPromise) {
|
|
1078
|
+
this.runPromise = null;
|
|
1079
|
+
this.runPromiseDeviceId = null;
|
|
1080
|
+
}
|
|
1081
|
+
};
|
|
1082
|
+
const isCurrentOwner = () => this.runPromise === runPromise;
|
|
1079
1083
|
const messages = this._messages;
|
|
1080
1084
|
const buffers = ProtocolV1.encodeTransportPackets(messages, name, data);
|
|
1081
1085
|
let timeout;
|
|
@@ -1096,6 +1100,9 @@ class ReactNativeBleTransport {
|
|
|
1096
1100
|
}
|
|
1097
1101
|
catch (e) {
|
|
1098
1102
|
onError(e);
|
|
1103
|
+
if (isWedgedWriteError(e)) {
|
|
1104
|
+
throw e;
|
|
1105
|
+
}
|
|
1099
1106
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleWriteCharacteristicError);
|
|
1100
1107
|
}
|
|
1101
1108
|
}
|
|
@@ -1123,6 +1130,9 @@ class ReactNativeBleTransport {
|
|
|
1123
1130
|
}
|
|
1124
1131
|
catch (e) {
|
|
1125
1132
|
onError(e);
|
|
1133
|
+
if (isWedgedWriteError(e)) {
|
|
1134
|
+
throw e;
|
|
1135
|
+
}
|
|
1126
1136
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleWriteCharacteristicError);
|
|
1127
1137
|
}
|
|
1128
1138
|
}
|
|
@@ -1133,8 +1143,8 @@ class ReactNativeBleTransport {
|
|
|
1133
1143
|
});
|
|
1134
1144
|
}
|
|
1135
1145
|
if (name === 'EmmcFileWrite') {
|
|
1136
|
-
yield writeChunkedData(buffers, data => transport.writeWithRetry(
|
|
1137
|
-
|
|
1146
|
+
yield writeChunkedData(buffers, data => this.writeBlePacket(uuid, data, payload => transport.writeWithRetry(payload), isCurrentOwner), e => {
|
|
1147
|
+
releaseOwnershipIfCurrent();
|
|
1138
1148
|
Log === null || Log === void 0 ? void 0 : Log.error('writeCharacteristic write error: ', e);
|
|
1139
1149
|
});
|
|
1140
1150
|
}
|
|
@@ -1150,7 +1160,7 @@ class ReactNativeBleTransport {
|
|
|
1150
1160
|
let attempt = 0;
|
|
1151
1161
|
while (true) {
|
|
1152
1162
|
try {
|
|
1153
|
-
yield transport.
|
|
1163
|
+
yield this.writeBlePacket(uuid, data, payload => transport.writeCharacteristic.writeWithoutResponse(payload), isCurrentOwner);
|
|
1154
1164
|
return;
|
|
1155
1165
|
}
|
|
1156
1166
|
catch (error) {
|
|
@@ -1169,7 +1179,7 @@ class ReactNativeBleTransport {
|
|
|
1169
1179
|
}
|
|
1170
1180
|
}
|
|
1171
1181
|
}), e => {
|
|
1172
|
-
|
|
1182
|
+
releaseOwnershipIfCurrent();
|
|
1173
1183
|
Log === null || Log === void 0 ? void 0 : Log.error('writeCharacteristic write error: ', e);
|
|
1174
1184
|
});
|
|
1175
1185
|
}
|
|
@@ -1177,17 +1187,14 @@ class ReactNativeBleTransport {
|
|
|
1177
1187
|
for (const o of buffers) {
|
|
1178
1188
|
const outData = o.toString('base64');
|
|
1179
1189
|
try {
|
|
1180
|
-
|
|
1181
|
-
if (shouldUseWriteWithResponse) {
|
|
1182
|
-
yield transport.writeCharacteristic.writeWithResponse(outData);
|
|
1183
|
-
}
|
|
1184
|
-
else {
|
|
1185
|
-
yield transport.writeCharacteristic.writeWithoutResponse(outData);
|
|
1186
|
-
}
|
|
1190
|
+
yield this.writeBlePacket(uuid, outData, payload => transport.writeCharacteristic.writeWithoutResponse(payload), isCurrentOwner);
|
|
1187
1191
|
}
|
|
1188
1192
|
catch (e) {
|
|
1189
1193
|
Log === null || Log === void 0 ? void 0 : Log.debug('writeCharacteristic write error: ', e);
|
|
1190
|
-
|
|
1194
|
+
releaseOwnershipIfCurrent();
|
|
1195
|
+
if (isWedgedWriteError(e)) {
|
|
1196
|
+
throw e;
|
|
1197
|
+
}
|
|
1191
1198
|
if (e.errorCode === reactNativeBlePlx.BleErrorCode.DeviceDisconnected) {
|
|
1192
1199
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceNotBonded);
|
|
1193
1200
|
}
|
|
@@ -1227,7 +1234,9 @@ class ReactNativeBleTransport {
|
|
|
1227
1234
|
Log === null || Log === void 0 ? void 0 : Log.error('call error: ', e);
|
|
1228
1235
|
}
|
|
1229
1236
|
const isProbeTimeout = name === 'GetFeatures' && (options === null || options === void 0 ? void 0 : options.timeoutMs) === PROTOCOL_PROBE_TIMEOUT_MS;
|
|
1237
|
+
const isStaleCall = this.runPromise !== runPromise;
|
|
1230
1238
|
if (!isProbeTimeout &&
|
|
1239
|
+
!isStaleCall &&
|
|
1231
1240
|
(e === null || e === void 0 ? void 0 : e.errorCode) === hdShared.HardwareErrorCode.BleTimeoutError) {
|
|
1232
1241
|
yield this.disconnect(uuid);
|
|
1233
1242
|
}
|
|
@@ -1298,7 +1307,10 @@ class ReactNativeBleTransport {
|
|
|
1298
1307
|
delete transportCache[session];
|
|
1299
1308
|
}
|
|
1300
1309
|
this.deviceProtocol.delete(session);
|
|
1310
|
+
this.probingProtocols.delete(session);
|
|
1301
1311
|
this.deviceProtocolHints.delete(session);
|
|
1312
|
+
this.sessionProtocols.delete(session);
|
|
1313
|
+
this.protocolReprobeFailures.delete(session);
|
|
1302
1314
|
this.protocolV2Assemblers.delete(session);
|
|
1303
1315
|
this.resetProtocolV2Frames(session);
|
|
1304
1316
|
try {
|
|
@@ -1319,6 +1331,91 @@ class ReactNativeBleTransport {
|
|
|
1319
1331
|
this.runPromise = null;
|
|
1320
1332
|
this.runPromiseDeviceId = null;
|
|
1321
1333
|
}
|
|
1334
|
+
connectWithTimeout(uuid, connect) {
|
|
1335
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1336
|
+
let timer;
|
|
1337
|
+
let timedOut = false;
|
|
1338
|
+
const pending = connect();
|
|
1339
|
+
pending.catch(() => undefined);
|
|
1340
|
+
try {
|
|
1341
|
+
const result = yield Promise.race([
|
|
1342
|
+
pending,
|
|
1343
|
+
new Promise((_, reject) => {
|
|
1344
|
+
timer = setTimeout(() => {
|
|
1345
|
+
timedOut = true;
|
|
1346
|
+
reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleConnectedError, `BLE connect timeout after ${BLE_CONNECT_TIMEOUT_MS}ms for ${uuid}`));
|
|
1347
|
+
}, BLE_CONNECT_TIMEOUT_MS);
|
|
1348
|
+
}),
|
|
1349
|
+
]);
|
|
1350
|
+
return result;
|
|
1351
|
+
}
|
|
1352
|
+
catch (error) {
|
|
1353
|
+
if (timedOut || isNativeOperationTimeoutError(error)) {
|
|
1354
|
+
this.abandonStalledConnection(uuid, timedOut ? 'connect-backstop' : 'connect-native');
|
|
1355
|
+
}
|
|
1356
|
+
throw error;
|
|
1357
|
+
}
|
|
1358
|
+
finally {
|
|
1359
|
+
if (timer)
|
|
1360
|
+
clearTimeout(timer);
|
|
1361
|
+
}
|
|
1362
|
+
});
|
|
1363
|
+
}
|
|
1364
|
+
resolveCharacteristicsWithTimeout(uuid, device) {
|
|
1365
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1366
|
+
let timer;
|
|
1367
|
+
let timedOut = false;
|
|
1368
|
+
const pending = this.resolveCharacteristics(device);
|
|
1369
|
+
pending.catch(() => undefined);
|
|
1370
|
+
try {
|
|
1371
|
+
const result = yield Promise.race([
|
|
1372
|
+
pending,
|
|
1373
|
+
new Promise((_, reject) => {
|
|
1374
|
+
timer = setTimeout(() => {
|
|
1375
|
+
timedOut = true;
|
|
1376
|
+
reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleConnectedError, `BLE GATT setup timeout after ${BLE_GATT_SETUP_TIMEOUT_MS}ms for ${uuid}`));
|
|
1377
|
+
}, BLE_GATT_SETUP_TIMEOUT_MS);
|
|
1378
|
+
}),
|
|
1379
|
+
]);
|
|
1380
|
+
this.connectionSetupTimeoutCounts.delete(uuid);
|
|
1381
|
+
return result;
|
|
1382
|
+
}
|
|
1383
|
+
catch (error) {
|
|
1384
|
+
if (timedOut || isNativeOperationTimeoutError(error)) {
|
|
1385
|
+
this.abandonStalledConnection(uuid, timedOut ? 'gatt-backstop' : 'gatt-native');
|
|
1386
|
+
}
|
|
1387
|
+
throw error;
|
|
1388
|
+
}
|
|
1389
|
+
finally {
|
|
1390
|
+
if (timer)
|
|
1391
|
+
clearTimeout(timer);
|
|
1392
|
+
}
|
|
1393
|
+
});
|
|
1394
|
+
}
|
|
1395
|
+
abandonStalledConnection(uuid, stage) {
|
|
1396
|
+
var _a, _b;
|
|
1397
|
+
const timeouts = ((_a = this.connectionSetupTimeoutCounts.get(uuid)) !== null && _a !== void 0 ? _a : 0) + 1;
|
|
1398
|
+
this.connectionSetupTimeoutCounts.set(uuid, timeouts);
|
|
1399
|
+
Log === null || Log === void 0 ? void 0 : Log.error('[ReactNativeBleTransport] BLE setup timed out:', uuid, {
|
|
1400
|
+
stage,
|
|
1401
|
+
setupTimeoutsSinceSuccess: timeouts,
|
|
1402
|
+
});
|
|
1403
|
+
(_b = this.blePlxManager) === null || _b === void 0 ? void 0 : _b.cancelDeviceConnection(uuid).catch(() => {
|
|
1404
|
+
});
|
|
1405
|
+
const stalled = transportCache[uuid];
|
|
1406
|
+
if (stalled) {
|
|
1407
|
+
delete transportCache[uuid];
|
|
1408
|
+
}
|
|
1409
|
+
this.deviceProtocol.delete(uuid);
|
|
1410
|
+
this.probingProtocols.delete(uuid);
|
|
1411
|
+
this.protocolV2Assemblers.delete(uuid);
|
|
1412
|
+
this.resetProtocolV2Frames(uuid);
|
|
1413
|
+
if (timeouts >= BLE_CONNECT_TIMEOUT_MANAGER_RESET_THRESHOLD) {
|
|
1414
|
+
Log === null || Log === void 0 ? void 0 : Log.error('[ReactNativeBleTransport] BLE setup wedged repeatedly, resetting BLE manager');
|
|
1415
|
+
this.resetPlxManager();
|
|
1416
|
+
this.connectionSetupTimeoutCounts.delete(uuid);
|
|
1417
|
+
}
|
|
1418
|
+
}
|
|
1322
1419
|
getCachedTransport(uuid) {
|
|
1323
1420
|
const transport = transportCache[uuid];
|
|
1324
1421
|
if (!transport) {
|
|
@@ -1326,6 +1423,82 @@ class ReactNativeBleTransport {
|
|
|
1326
1423
|
}
|
|
1327
1424
|
return transport;
|
|
1328
1425
|
}
|
|
1426
|
+
writeBlePacket(uuid, data, write, isCurrentOwner) {
|
|
1427
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1428
|
+
let timer;
|
|
1429
|
+
let timedOut = false;
|
|
1430
|
+
try {
|
|
1431
|
+
yield Promise.race([
|
|
1432
|
+
write(data),
|
|
1433
|
+
new Promise((_, reject) => {
|
|
1434
|
+
timer = setTimeout(() => {
|
|
1435
|
+
timedOut = true;
|
|
1436
|
+
reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleWriteCharacteristicError, `BLE write timeout after ${BLE_WRITE_PACKET_TIMEOUT_MS}ms`));
|
|
1437
|
+
}, BLE_WRITE_PACKET_TIMEOUT_MS);
|
|
1438
|
+
}),
|
|
1439
|
+
]);
|
|
1440
|
+
this.writeTimeoutCounts.delete(uuid);
|
|
1441
|
+
}
|
|
1442
|
+
catch (error) {
|
|
1443
|
+
if (timedOut) {
|
|
1444
|
+
if (isCurrentOwner && !isCurrentOwner()) {
|
|
1445
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] stale BLE write timed out, link kept:', uuid);
|
|
1446
|
+
}
|
|
1447
|
+
else {
|
|
1448
|
+
this.tearDownWedgedLink(uuid);
|
|
1449
|
+
}
|
|
1450
|
+
}
|
|
1451
|
+
throw error;
|
|
1452
|
+
}
|
|
1453
|
+
finally {
|
|
1454
|
+
if (timer)
|
|
1455
|
+
clearTimeout(timer);
|
|
1456
|
+
}
|
|
1457
|
+
});
|
|
1458
|
+
}
|
|
1459
|
+
tearDownWedgedLink(uuid) {
|
|
1460
|
+
var _a;
|
|
1461
|
+
const timeouts = ((_a = this.writeTimeoutCounts.get(uuid)) !== null && _a !== void 0 ? _a : 0) + 1;
|
|
1462
|
+
this.writeTimeoutCounts.set(uuid, timeouts);
|
|
1463
|
+
Log === null || Log === void 0 ? void 0 : Log.error('[ReactNativeBleTransport] BLE write timed out, tearing down link:', uuid, {
|
|
1464
|
+
consecutiveWriteTimeouts: timeouts,
|
|
1465
|
+
});
|
|
1466
|
+
const wedged = transportCache[uuid];
|
|
1467
|
+
this.disconnect(uuid).catch(error => {
|
|
1468
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] wedged link teardown failed (ignored):', error);
|
|
1469
|
+
});
|
|
1470
|
+
if (wedged && transportCache[uuid] === wedged) {
|
|
1471
|
+
delete transportCache[uuid];
|
|
1472
|
+
}
|
|
1473
|
+
this.deviceProtocol.delete(uuid);
|
|
1474
|
+
this.probingProtocols.delete(uuid);
|
|
1475
|
+
this.protocolV2Assemblers.delete(uuid);
|
|
1476
|
+
this.resetProtocolV2Frames(uuid);
|
|
1477
|
+
if (timeouts >= BLE_WRITE_TIMEOUT_MANAGER_RESET_THRESHOLD) {
|
|
1478
|
+
Log === null || Log === void 0 ? void 0 : Log.error('[ReactNativeBleTransport] BLE writes wedged repeatedly, resetting BLE manager');
|
|
1479
|
+
this.resetPlxManager();
|
|
1480
|
+
this.writeTimeoutCounts.delete(uuid);
|
|
1481
|
+
}
|
|
1482
|
+
}
|
|
1483
|
+
resetPlxManager() {
|
|
1484
|
+
const manager = this.blePlxManager;
|
|
1485
|
+
this.blePlxManager = undefined;
|
|
1486
|
+
Object.keys(transportCache).forEach(key => {
|
|
1487
|
+
delete transportCache[key];
|
|
1488
|
+
});
|
|
1489
|
+
this.deviceProtocol.clear();
|
|
1490
|
+
this.probingProtocols.clear();
|
|
1491
|
+
this.sessionProtocols.clear();
|
|
1492
|
+
this.protocolReprobeFailures.clear();
|
|
1493
|
+
this.monitorTokens.clear();
|
|
1494
|
+
this.protocolV2Assemblers.clear();
|
|
1495
|
+
try {
|
|
1496
|
+
manager === null || manager === void 0 ? void 0 : manager.destroy();
|
|
1497
|
+
}
|
|
1498
|
+
catch (error) {
|
|
1499
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] BLE manager destroy failed (ignored):', error);
|
|
1500
|
+
}
|
|
1501
|
+
}
|
|
1329
1502
|
createProtocolMismatchError(expected) {
|
|
1330
1503
|
return hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Device protocol mismatch: expected ${expected}, but device did not respond to expected protocol`);
|
|
1331
1504
|
}
|
|
@@ -1333,24 +1506,24 @@ class ReactNativeBleTransport {
|
|
|
1333
1506
|
return hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleTimeoutError, 'Unable to detect BLE protocol: device did not respond to Protocol V1 GetFeatures or Protocol V2 Ping');
|
|
1334
1507
|
}
|
|
1335
1508
|
clearProbeProtocol(uuid, protocol) {
|
|
1509
|
+
if (this.probingProtocols.get(uuid) === protocol) {
|
|
1510
|
+
this.probingProtocols.delete(uuid);
|
|
1511
|
+
}
|
|
1336
1512
|
if (this.deviceProtocol.get(uuid) === protocol) {
|
|
1337
1513
|
this.deviceProtocol.delete(uuid);
|
|
1338
1514
|
}
|
|
1339
1515
|
}
|
|
1516
|
+
getActiveProtocol(uuid) {
|
|
1517
|
+
var _a;
|
|
1518
|
+
return (_a = this.deviceProtocol.get(uuid)) !== null && _a !== void 0 ? _a : this.probingProtocols.get(uuid);
|
|
1519
|
+
}
|
|
1340
1520
|
detectProtocol(uuid, expectedProtocol, protocolHint, rebuildTransport) {
|
|
1521
|
+
var _a;
|
|
1341
1522
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1342
|
-
if (reactNative.Platform.OS === 'ios' && expectedProtocol) {
|
|
1343
|
-
this.deviceProtocol.set(uuid, expectedProtocol);
|
|
1344
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] protocol selected', {
|
|
1345
|
-
deviceId: uuid,
|
|
1346
|
-
protocol: expectedProtocol,
|
|
1347
|
-
source: 'expected',
|
|
1348
|
-
});
|
|
1349
|
-
return expectedProtocol;
|
|
1350
|
-
}
|
|
1351
1523
|
if (expectedProtocol === 'V1') {
|
|
1352
1524
|
if (yield this.probeProtocolV1(uuid)) {
|
|
1353
1525
|
this.deviceProtocol.set(uuid, 'V1');
|
|
1526
|
+
this.sessionProtocols.set(uuid, 'V1');
|
|
1354
1527
|
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] protocol detected', {
|
|
1355
1528
|
deviceId: uuid,
|
|
1356
1529
|
protocol: 'V1',
|
|
@@ -1363,6 +1536,7 @@ class ReactNativeBleTransport {
|
|
|
1363
1536
|
if (expectedProtocol === 'V2') {
|
|
1364
1537
|
if (yield this.probeProtocolV2(uuid)) {
|
|
1365
1538
|
this.deviceProtocol.set(uuid, 'V2');
|
|
1539
|
+
this.sessionProtocols.set(uuid, 'V2');
|
|
1366
1540
|
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] protocol detected', {
|
|
1367
1541
|
deviceId: uuid,
|
|
1368
1542
|
protocol: 'V2',
|
|
@@ -1372,7 +1546,13 @@ class ReactNativeBleTransport {
|
|
|
1372
1546
|
}
|
|
1373
1547
|
throw this.createProtocolMismatchError(expectedProtocol);
|
|
1374
1548
|
}
|
|
1375
|
-
const
|
|
1549
|
+
const sessionProtocol = this.sessionProtocols.get(uuid);
|
|
1550
|
+
const reprobeFailures = (_a = this.protocolReprobeFailures.get(uuid)) !== null && _a !== void 0 ? _a : 0;
|
|
1551
|
+
const fullProbeOrder = protocolHint === 'V2' || this.deviceProtocol.get(uuid) === 'V2' ? ['V2', 'V1'] : ['V1', 'V2'];
|
|
1552
|
+
const trustSessionProtocol = sessionProtocol !== undefined &&
|
|
1553
|
+
!protocolHint &&
|
|
1554
|
+
reprobeFailures < PROTOCOL_REPROBE_FALLBACK_ATTEMPTS;
|
|
1555
|
+
const probeOrder = trustSessionProtocol ? [sessionProtocol] : fullProbeOrder;
|
|
1376
1556
|
for (let i = 0; i < probeOrder.length; i += 1) {
|
|
1377
1557
|
const protocol = probeOrder[i];
|
|
1378
1558
|
if (i > 0) {
|
|
@@ -1387,6 +1567,8 @@ class ReactNativeBleTransport {
|
|
|
1387
1567
|
const detected = protocol === 'V1' ? yield this.probeProtocolV1(uuid) : yield this.probeProtocolV2(uuid);
|
|
1388
1568
|
if (detected) {
|
|
1389
1569
|
this.deviceProtocol.set(uuid, protocol);
|
|
1570
|
+
this.sessionProtocols.set(uuid, protocol);
|
|
1571
|
+
this.protocolReprobeFailures.delete(uuid);
|
|
1390
1572
|
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] protocol detected', {
|
|
1391
1573
|
deviceId: uuid,
|
|
1392
1574
|
protocol,
|
|
@@ -1395,7 +1577,14 @@ class ReactNativeBleTransport {
|
|
|
1395
1577
|
return protocol;
|
|
1396
1578
|
}
|
|
1397
1579
|
}
|
|
1580
|
+
if (trustSessionProtocol) {
|
|
1581
|
+
this.protocolReprobeFailures.set(uuid, reprobeFailures + 1);
|
|
1582
|
+
}
|
|
1583
|
+
else {
|
|
1584
|
+
this.protocolReprobeFailures.delete(uuid);
|
|
1585
|
+
}
|
|
1398
1586
|
this.deviceProtocol.delete(uuid);
|
|
1587
|
+
this.probingProtocols.delete(uuid);
|
|
1399
1588
|
throw this.createProtocolDetectionError();
|
|
1400
1589
|
});
|
|
1401
1590
|
}
|
|
@@ -1447,13 +1636,17 @@ class ReactNativeBleTransport {
|
|
|
1447
1636
|
return false;
|
|
1448
1637
|
}
|
|
1449
1638
|
try {
|
|
1450
|
-
this.
|
|
1639
|
+
this.probingProtocols.set(uuid, 'V1');
|
|
1451
1640
|
yield this.callProtocolV1(uuid, 'GetFeatures', {}, { timeoutMs: PROTOCOL_PROBE_TIMEOUT_MS });
|
|
1641
|
+
this.probingProtocols.delete(uuid);
|
|
1452
1642
|
return true;
|
|
1453
1643
|
}
|
|
1454
1644
|
catch (error) {
|
|
1455
1645
|
this.clearProbeProtocol(uuid, 'V1');
|
|
1456
1646
|
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V1 GetFeatures probe failed:', error);
|
|
1647
|
+
if (isWedgedWriteError(error)) {
|
|
1648
|
+
throw error;
|
|
1649
|
+
}
|
|
1457
1650
|
return false;
|
|
1458
1651
|
}
|
|
1459
1652
|
});
|
|
@@ -1464,7 +1657,7 @@ class ReactNativeBleTransport {
|
|
|
1464
1657
|
if (!this._messages || !this._messagesV2) {
|
|
1465
1658
|
return false;
|
|
1466
1659
|
}
|
|
1467
|
-
this.
|
|
1660
|
+
this.probingProtocols.set(uuid, 'V2');
|
|
1468
1661
|
(_a = this.protocolV2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
|
|
1469
1662
|
const detected = yield transport.probeProtocolV2({
|
|
1470
1663
|
call: (name, data, options) => this.callProtocolV2(uuid, name, data, options),
|
|
@@ -1480,6 +1673,9 @@ class ReactNativeBleTransport {
|
|
|
1480
1673
|
if (!detected) {
|
|
1481
1674
|
this.clearProbeProtocol(uuid, 'V2');
|
|
1482
1675
|
}
|
|
1676
|
+
else {
|
|
1677
|
+
this.probingProtocols.delete(uuid);
|
|
1678
|
+
}
|
|
1483
1679
|
return detected;
|
|
1484
1680
|
});
|
|
1485
1681
|
}
|
|
@@ -1551,10 +1747,8 @@ class ReactNativeBleTransport {
|
|
|
1551
1747
|
}
|
|
1552
1748
|
});
|
|
1553
1749
|
}
|
|
1554
|
-
writeProtocolV2Packet(transport, base64, context, assertCurrentGeneration) {
|
|
1750
|
+
writeProtocolV2Packet(uuid, transport, base64, context, assertCurrentGeneration) {
|
|
1555
1751
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1556
|
-
const shouldUseWriteWithResponse = transport.writeCharacteristic.isWritableWithResponse &&
|
|
1557
|
-
(context.writeWithResponse === true || (reactNative.Platform.OS === 'ios' && !context.highVolume));
|
|
1558
1752
|
let attempt = 0;
|
|
1559
1753
|
for (;;) {
|
|
1560
1754
|
assertCurrentGeneration();
|
|
@@ -1562,12 +1756,15 @@ class ReactNativeBleTransport {
|
|
|
1562
1756
|
throw new Error(`Protocol V2 BLE write aborted for ${context.messageName}`);
|
|
1563
1757
|
}
|
|
1564
1758
|
try {
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1759
|
+
yield this.writeBlePacket(uuid, base64, payload => transport.writeCharacteristic.writeWithoutResponse(payload), () => {
|
|
1760
|
+
try {
|
|
1761
|
+
assertCurrentGeneration();
|
|
1762
|
+
return !context.signal.aborted;
|
|
1763
|
+
}
|
|
1764
|
+
catch (_a) {
|
|
1765
|
+
return false;
|
|
1766
|
+
}
|
|
1767
|
+
});
|
|
1571
1768
|
assertCurrentGeneration();
|
|
1572
1769
|
return;
|
|
1573
1770
|
}
|
|
@@ -1588,7 +1785,7 @@ class ReactNativeBleTransport {
|
|
|
1588
1785
|
}
|
|
1589
1786
|
});
|
|
1590
1787
|
}
|
|
1591
|
-
writeProtocolV2Frame(transport$1, frame, context, assertCurrentGeneration) {
|
|
1788
|
+
writeProtocolV2Frame(uuid, transport$1, frame, context, assertCurrentGeneration) {
|
|
1592
1789
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1593
1790
|
const tuning = getProtocolV2BleTuning();
|
|
1594
1791
|
const packetCapacity = resolveProtocolV2PacketCapacity({
|
|
@@ -1597,21 +1794,17 @@ class ReactNativeBleTransport {
|
|
|
1597
1794
|
androidPacketLength: tuning.androidPacketLength,
|
|
1598
1795
|
mtu: reactNative.Platform.OS === 'android' ? transport$1.mtuSize : undefined,
|
|
1599
1796
|
});
|
|
1600
|
-
const initialDelayMs = reactNative.Platform.OS === 'ios' && !context.highVolume && frame.length <= packetCapacity
|
|
1601
|
-
? IOS_PROTOCOL_V2_CONTROL_WRITE_DELAY_MS
|
|
1602
|
-
: 0;
|
|
1603
1797
|
yield transport.writeProtocolV2BleFrame({
|
|
1604
1798
|
frame,
|
|
1605
1799
|
packetCapacity,
|
|
1606
1800
|
assertActive: assertCurrentGeneration,
|
|
1607
1801
|
signal: context.signal,
|
|
1608
1802
|
abortMessage: `Protocol V2 BLE write aborted for ${context.messageName}`,
|
|
1609
|
-
initialDelayMs,
|
|
1610
1803
|
burstSize: FIRMWARE_UPLOAD_WRITE_BURST_SIZE,
|
|
1611
1804
|
burstPauseMs: FIRMWARE_UPLOAD_WRITE_PAUSE_MS,
|
|
1612
1805
|
flushDelayMs: FIRMWARE_UPLOAD_WRITE_FLUSH_DELAY_MS,
|
|
1613
1806
|
wait: delay,
|
|
1614
|
-
writePacket: packet => this.writeProtocolV2Packet(transport$1, buffer.Buffer.from(packet).toString('base64'), context, assertCurrentGeneration),
|
|
1807
|
+
writePacket: packet => this.writeProtocolV2Packet(uuid, transport$1, buffer.Buffer.from(packet).toString('base64'), context, assertCurrentGeneration),
|
|
1615
1808
|
});
|
|
1616
1809
|
});
|
|
1617
1810
|
}
|
|
@@ -1626,7 +1819,7 @@ class ReactNativeBleTransport {
|
|
|
1626
1819
|
const tuning = getProtocolV2BleTuning();
|
|
1627
1820
|
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V2 high-volume write configured', {
|
|
1628
1821
|
name,
|
|
1629
|
-
writeMode:
|
|
1822
|
+
writeMode: 'withoutResponse',
|
|
1630
1823
|
packetCapacity: reactNative.Platform.OS === 'ios' ? tuning.iosPacketLength : tuning.androidPacketLength,
|
|
1631
1824
|
});
|
|
1632
1825
|
}
|
|
@@ -1660,7 +1853,7 @@ class ReactNativeBleTransport {
|
|
|
1660
1853
|
writeFrame: (frame, context) => __awaiter(this, void 0, void 0, function* () {
|
|
1661
1854
|
assertCurrentGeneration();
|
|
1662
1855
|
const currentTransport = this.getCachedTransport(uuid);
|
|
1663
|
-
yield this.writeProtocolV2Frame(currentTransport, frame, context, assertCurrentGeneration);
|
|
1856
|
+
yield this.writeProtocolV2Frame(uuid, currentTransport, frame, context, assertCurrentGeneration);
|
|
1664
1857
|
}),
|
|
1665
1858
|
readFrame: () => __awaiter(this, void 0, void 0, function* () {
|
|
1666
1859
|
assertCurrentGeneration();
|
|
@@ -1681,10 +1874,16 @@ class ReactNativeBleTransport {
|
|
|
1681
1874
|
};
|
|
1682
1875
|
}
|
|
1683
1876
|
getProtocolType(path) {
|
|
1684
|
-
return this.
|
|
1877
|
+
return this.getActiveProtocol(path);
|
|
1685
1878
|
}
|
|
1686
1879
|
}
|
|
1687
1880
|
|
|
1881
|
+
exports.BLE_CONNECT_TIMEOUT_MANAGER_RESET_THRESHOLD = BLE_CONNECT_TIMEOUT_MANAGER_RESET_THRESHOLD;
|
|
1882
|
+
exports.BLE_CONNECT_TIMEOUT_MS = BLE_CONNECT_TIMEOUT_MS;
|
|
1883
|
+
exports.BLE_GATT_SETUP_TIMEOUT_MS = BLE_GATT_SETUP_TIMEOUT_MS;
|
|
1884
|
+
exports.BLE_WRITE_PACKET_TIMEOUT_MS = BLE_WRITE_PACKET_TIMEOUT_MS;
|
|
1885
|
+
exports.BLE_WRITE_TIMEOUT_MANAGER_RESET_THRESHOLD = BLE_WRITE_TIMEOUT_MANAGER_RESET_THRESHOLD;
|
|
1886
|
+
exports.PROTOCOL_REPROBE_FALLBACK_ATTEMPTS = PROTOCOL_REPROBE_FALLBACK_ATTEMPTS;
|
|
1688
1887
|
exports.configureProtocolV2BleTuning = configureProtocolV2BleTuning;
|
|
1689
1888
|
exports["default"] = ReactNativeBleTransport;
|
|
1690
1889
|
exports.getFirmwareUploadWriteRetryType = getFirmwareUploadWriteRetryType;
|