@onekeyfe/hd-transport-react-native 1.2.0-alpha.14 → 1.2.0-alpha.140
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 +2 -4
- package/dist/BleTransport.d.ts.map +1 -1
- package/dist/bleStrategy.d.ts +7 -0
- package/dist/bleStrategy.d.ts.map +1 -1
- package/dist/constants.d.ts +2 -2
- package/dist/constants.d.ts.map +1 -1
- package/dist/index.d.ts +123 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +869 -292
- package/dist/transportLog.d.ts +1 -12
- package/dist/transportLog.d.ts.map +1 -1
- package/dist/types.d.ts +1 -0
- package/dist/types.d.ts.map +1 -1
- package/jest.config.js +10 -0
- package/package.json +6 -5
- package/src/BleTransport.ts +10 -42
- package/src/__tests__/BleTransport.test.ts +114 -0
- package/src/__tests__/bleStrategy.test.ts +93 -5
- package/src/__tests__/connectTimeout.test.ts +292 -0
- package/src/__tests__/constants.test.ts +20 -0
- package/src/__tests__/enumerate.test.ts +150 -0
- package/src/__tests__/protocolReprobe.test.ts +156 -0
- package/src/__tests__/protocolV1SchemaFixture.ts +39 -0
- package/src/__tests__/protocolV2Link.test.ts +829 -32
- package/src/__tests__/staleCallTimeout.test.ts +210 -0
- package/src/__tests__/writePacketTimeout.test.ts +305 -0
- package/src/bleStrategy.ts +26 -11
- package/src/constants.ts +9 -14
- package/src/index.ts +1137 -268
- package/src/transportLog.ts +1 -18
- package/src/types.ts +1 -0
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
|
|
96
|
+
const IOS_PROTOCOL_V2_PACKET_LENGTH = 244;
|
|
97
|
+
const ANDROID_PROTOCOL_V2_PACKET_LENGTH = 244;
|
|
97
98
|
const ClassicServiceUUID = '00000001-0000-1000-8000-00805f9b34fb';
|
|
98
99
|
const OneKeyServices = {
|
|
99
100
|
classic: {
|
|
@@ -117,36 +118,38 @@ const getInfosForServiceUuid = (serviceUuid, deviceType) => {
|
|
|
117
118
|
return null;
|
|
118
119
|
}
|
|
119
120
|
const normalizedServiceUuid = normalizeBleUuid(serviceUuid);
|
|
120
|
-
const service = (_a = services[serviceUuid]) !== null && _a !== void 0 ? _a : Object.values(services).find(item => normalizeBleUuid(item.serviceUuid) === normalizedServiceUuid
|
|
121
|
+
const service = (_a = services[serviceUuid]) !== null && _a !== void 0 ? _a : Object.values(services).find(item => normalizeBleUuid(item.serviceUuid) === normalizedServiceUuid ||
|
|
122
|
+
hdShared.matchesKnownBleUuid(serviceUuid, hdShared.createKnownBleUuidAliases(item.serviceUuid)));
|
|
121
123
|
if (!service) {
|
|
122
124
|
return null;
|
|
123
125
|
}
|
|
124
126
|
return service;
|
|
125
127
|
};
|
|
126
128
|
const normalizeBleUuid = (uuid) => (uuid !== null && uuid !== void 0 ? uuid : '').replace(/-/g, '').toLowerCase();
|
|
127
|
-
const getBleUuidKey = (uuid) => {
|
|
128
|
-
const normalized = normalizeBleUuid(uuid);
|
|
129
|
-
return normalized.length >= 8 ? normalized.substring(4, 8) : normalized;
|
|
130
|
-
};
|
|
131
129
|
const isSameBleUuid = (left, right) => {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
return (
|
|
135
|
-
(getBleUuidKey(left) !== '' && getBleUuidKey(left) === getBleUuidKey(right)));
|
|
130
|
+
if (!left || !right)
|
|
131
|
+
return false;
|
|
132
|
+
return hdShared.matchesKnownBleUuid(left, hdShared.createKnownBleUuidAliases(right));
|
|
136
133
|
};
|
|
137
134
|
|
|
138
135
|
function hasWritableCapability(characteristic) {
|
|
139
136
|
return !!(characteristic.isWritableWithResponse || characteristic.isWritableWithoutResponse);
|
|
140
137
|
}
|
|
141
|
-
function resolveProtocolV2PacketCapacity({ platform, iosPacketLength =
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
138
|
+
function resolveProtocolV2PacketCapacity({ platform, iosPacketLength = IOS_PROTOCOL_V2_PACKET_LENGTH, androidPacketLength = ANDROID_PROTOCOL_V2_PACKET_LENGTH, mtu, }) {
|
|
139
|
+
const negotiatedMtu = typeof mtu === 'number' && Number.isFinite(mtu) && mtu > 3 ? Math.floor(mtu) : 23;
|
|
140
|
+
const payloadLength = negotiatedMtu - 3;
|
|
141
|
+
const configuredPacketLength = platform === 'ios' ? iosPacketLength : androidPacketLength;
|
|
142
|
+
return Math.min(configuredPacketLength, payloadLength);
|
|
143
|
+
}
|
|
144
|
+
function shouldRefreshNegotiatedMtu(mtu) {
|
|
145
|
+
return typeof mtu !== 'number' || !Number.isFinite(mtu) || mtu <= 23;
|
|
146
|
+
}
|
|
147
|
+
function shouldWriteProtocolV2WithResponse({ platform, highThroughput, requestedWithResponse, characteristic, }) {
|
|
148
|
+
if (!characteristic.isWritableWithResponse)
|
|
149
|
+
return false;
|
|
150
|
+
if (!characteristic.isWritableWithoutResponse)
|
|
151
|
+
return true;
|
|
152
|
+
return requestedWithResponse === true || (platform === 'ios' && !highThroughput);
|
|
150
153
|
}
|
|
151
154
|
|
|
152
155
|
const timer = process.env.NODE_ENV === 'development'
|
|
@@ -203,59 +206,20 @@ const isHeaderChunk = (chunk) => {
|
|
|
203
206
|
return false;
|
|
204
207
|
};
|
|
205
208
|
|
|
206
|
-
const Log$1 = bleLogger;
|
|
207
209
|
class BleTransport {
|
|
208
210
|
constructor(device, writeCharacteristic, notifyCharacteristic) {
|
|
209
211
|
this.name = 'ReactNativeBleTransport';
|
|
210
|
-
this.mtuSize = 23;
|
|
211
212
|
this.id = device.id;
|
|
212
213
|
this.device = device;
|
|
213
214
|
this.writeCharacteristic = writeCharacteristic;
|
|
214
215
|
this.notifyCharacteristic = notifyCharacteristic;
|
|
215
216
|
}
|
|
216
|
-
writeWithRetry(data
|
|
217
|
+
writeWithRetry(data) {
|
|
217
218
|
return __awaiter(this, void 0, void 0, function* () {
|
|
218
|
-
|
|
219
|
-
yield this.writeCharacteristic.writeWithoutResponse(data);
|
|
220
|
-
}
|
|
221
|
-
catch (error) {
|
|
222
|
-
Log$1 === null || Log$1 === void 0 ? void 0 : Log$1.debug(`Write retry attempt ${BleTransport.MAX_RETRIES - retryCount + 1}, error: ${error}`);
|
|
223
|
-
if (retryCount > 0) {
|
|
224
|
-
yield hdShared.wait(BleTransport.RETRY_DELAY);
|
|
225
|
-
if (error.errorCode === reactNativeBlePlx.BleErrorCode.DeviceDisconnected ||
|
|
226
|
-
error.errorCode === reactNativeBlePlx.BleErrorCode.CharacteristicNotFound) {
|
|
227
|
-
try {
|
|
228
|
-
yield this.device.connect();
|
|
229
|
-
yield this.device.discoverAllServicesAndCharacteristics();
|
|
230
|
-
}
|
|
231
|
-
catch (e) {
|
|
232
|
-
Log$1 === null || Log$1 === void 0 ? void 0 : Log$1.debug(`Connect or discoverAllServicesAndCharacteristics error: ${e}`);
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
else {
|
|
236
|
-
Log$1 === null || Log$1 === void 0 ? void 0 : Log$1.debug(`writeCharacteristic error: ${error}`);
|
|
237
|
-
}
|
|
238
|
-
return this.writeWithRetry(data, retryCount - 1);
|
|
239
|
-
}
|
|
240
|
-
throw error;
|
|
241
|
-
}
|
|
219
|
+
yield this.writeCharacteristic.writeWithoutResponse(data);
|
|
242
220
|
});
|
|
243
221
|
}
|
|
244
222
|
}
|
|
245
|
-
BleTransport.MAX_RETRIES = 5;
|
|
246
|
-
BleTransport.RETRY_DELAY = 2000;
|
|
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
223
|
|
|
260
224
|
const { check, ProtocolV1, parseConfigure } = transport__default["default"];
|
|
261
225
|
const Log = bleLogger;
|
|
@@ -264,10 +228,35 @@ const FIRMWARE_UPLOAD_WRITE_BURST_SIZE = reactNative.Platform.OS === 'ios' ? 4 :
|
|
|
264
228
|
const FIRMWARE_UPLOAD_WRITE_PAUSE_MS = reactNative.Platform.OS === 'ios' ? 8 : 10;
|
|
265
229
|
const FIRMWARE_UPLOAD_WRITE_FLUSH_DELAY_MS = reactNative.Platform.OS === 'ios' ? 24 : 30;
|
|
266
230
|
const FIRMWARE_UPLOAD_WRITE_MAX_RETRIES = 8;
|
|
267
|
-
const FIRMWARE_UPLOAD_RECONNECT_RETRY_DELAY_MS = 2000;
|
|
268
231
|
const ANDROID_FIRMWARE_UPLOAD_PACKET_LENGTH = 192;
|
|
269
232
|
const FIRMWARE_UPLOAD_WRITE_PACKET_CAPACITY = reactNative.Platform.OS === 'ios' ? IOS_PACKET_LENGTH : ANDROID_FIRMWARE_UPLOAD_PACKET_LENGTH;
|
|
270
233
|
const ANDROID_GATT_CONGESTED_STATUS = 143;
|
|
234
|
+
const isAsciiWhitespace = (code) => code === 0x09 ||
|
|
235
|
+
code === 0x0a ||
|
|
236
|
+
code === 0x0b ||
|
|
237
|
+
code === 0x0c ||
|
|
238
|
+
code === 0x0d ||
|
|
239
|
+
code === 0x20;
|
|
240
|
+
const hasGattCongestedStatus = (text) => {
|
|
241
|
+
let searchFrom = 0;
|
|
242
|
+
while (searchFrom < text.length) {
|
|
243
|
+
const statusIndex = text.indexOf('status', searchFrom);
|
|
244
|
+
if (statusIndex < 0)
|
|
245
|
+
return false;
|
|
246
|
+
let cursor = statusIndex + 'status'.length;
|
|
247
|
+
while (cursor < text.length && isAsciiWhitespace(text.charCodeAt(cursor)))
|
|
248
|
+
cursor += 1;
|
|
249
|
+
if (text[cursor] === ':' || text[cursor] === '=') {
|
|
250
|
+
cursor += 1;
|
|
251
|
+
while (cursor < text.length && isAsciiWhitespace(text.charCodeAt(cursor)))
|
|
252
|
+
cursor += 1;
|
|
253
|
+
}
|
|
254
|
+
if (text.startsWith(String(ANDROID_GATT_CONGESTED_STATUS), cursor))
|
|
255
|
+
return true;
|
|
256
|
+
searchFrom = statusIndex + 'status'.length;
|
|
257
|
+
}
|
|
258
|
+
return false;
|
|
259
|
+
};
|
|
271
260
|
const delay = (ms) => new Promise(resolve => {
|
|
272
261
|
setTimeout(resolve, ms);
|
|
273
262
|
});
|
|
@@ -275,10 +264,6 @@ const getFirmwareUploadWriteRetryType = (error) => {
|
|
|
275
264
|
if (!error || typeof error !== 'object')
|
|
276
265
|
return null;
|
|
277
266
|
const bleWriteError = error;
|
|
278
|
-
if (bleWriteError.errorCode === reactNativeBlePlx.BleErrorCode.DeviceDisconnected ||
|
|
279
|
-
bleWriteError.errorCode === reactNativeBlePlx.BleErrorCode.CharacteristicNotFound) {
|
|
280
|
-
return 'reconnectable';
|
|
281
|
-
}
|
|
282
267
|
if (bleWriteError.androidErrorCode === ANDROID_GATT_CONGESTED_STATUS ||
|
|
283
268
|
bleWriteError.status === ANDROID_GATT_CONGESTED_STATUS) {
|
|
284
269
|
return 'congested';
|
|
@@ -286,18 +271,24 @@ const getFirmwareUploadWriteRetryType = (error) => {
|
|
|
286
271
|
const text = [bleWriteError.reason, bleWriteError.message, bleWriteError.name]
|
|
287
272
|
.filter(value => typeof value === 'string')
|
|
288
273
|
.join(' ');
|
|
289
|
-
return
|
|
274
|
+
return text.includes('GATT_CONGESTED') || hasGattCongestedStatus(text) ? 'congested' : null;
|
|
290
275
|
};
|
|
291
276
|
const resolveFirmwareUploadRetryDelay = (attempt, baseDelayMs = 200, maxDelayMs = 1200) => Math.min(baseDelayMs * Math.pow(2, attempt), maxDelayMs);
|
|
292
|
-
const
|
|
293
|
-
const PROTOCOL_PROBE_TIMEOUT_MS = 1000;
|
|
277
|
+
const PROTOCOL_PROBE_TIMEOUT_MS = 3000;
|
|
294
278
|
const PROTOCOL_V2_PROBE_TIMEOUT_MS = 10000;
|
|
295
|
-
const
|
|
279
|
+
const BLE_WRITE_PACKET_TIMEOUT_MS = 10000;
|
|
280
|
+
const BLE_NATIVE_TEARDOWN_TIMEOUT_MS = 3000;
|
|
281
|
+
const WEDGED_WRITE_MESSAGE = 'BLE write timeout after';
|
|
282
|
+
const isWedgedWriteError = (error) => (error === null || error === void 0 ? void 0 : error.errorCode) === hdShared.HardwareErrorCode.BleWriteCharacteristicError &&
|
|
283
|
+
typeof (error === null || error === void 0 ? void 0 : error.message) === 'string' &&
|
|
284
|
+
error.message.startsWith(WEDGED_WRITE_MESSAGE);
|
|
285
|
+
const BLE_WRITE_TIMEOUT_MANAGER_RESET_THRESHOLD = 2;
|
|
286
|
+
const DEVICE_SCAN_TIMEOUT_MS = 3000;
|
|
296
287
|
const IOS_NOTIFY_READY_DELAY_MS = 150;
|
|
297
288
|
const ANDROID_NOTIFY_READY_DELAY_MS = 300;
|
|
298
289
|
const DEFAULT_PROTOCOL_V2_BLE_TUNING = {
|
|
299
|
-
iosPacketLength:
|
|
300
|
-
androidPacketLength:
|
|
290
|
+
iosPacketLength: IOS_PROTOCOL_V2_PACKET_LENGTH,
|
|
291
|
+
androidPacketLength: ANDROID_PROTOCOL_V2_PACKET_LENGTH,
|
|
301
292
|
};
|
|
302
293
|
let protocolV2BleTuning = Object.assign({}, DEFAULT_PROTOCOL_V2_BLE_TUNING);
|
|
303
294
|
const normalizePositiveInteger = (value, fallback) => {
|
|
@@ -326,19 +317,29 @@ function inferProtocolHintFromDeviceName(name) {
|
|
|
326
317
|
function getDeviceDisplayName(device) {
|
|
327
318
|
return (device === null || device === void 0 ? void 0 : device.name) || (device === null || device === void 0 ? void 0 : device.localName) || null;
|
|
328
319
|
}
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
}
|
|
336
|
-
const ANDROID_REQUEST_MTU = 256;
|
|
320
|
+
const IOS_REQUEST_MTU = 247;
|
|
321
|
+
const ANDROID_REQUEST_MTU = 517;
|
|
322
|
+
const BLE_MTU_REFRESH_RETRY_DELAY_MS = 200;
|
|
323
|
+
const ANDROID_HIGH_PRIORITY_IDLE_MS = 1000;
|
|
324
|
+
const getRequestedBleMtu = () => reactNative.Platform.OS === 'android' ? ANDROID_REQUEST_MTU : IOS_REQUEST_MTU;
|
|
325
|
+
const BLE_NATIVE_CONNECT_TIMEOUT_MS = 3000;
|
|
337
326
|
const connectOptions = {
|
|
338
|
-
requestMTU:
|
|
339
|
-
timeout:
|
|
327
|
+
requestMTU: getRequestedBleMtu(),
|
|
328
|
+
timeout: BLE_NATIVE_CONNECT_TIMEOUT_MS,
|
|
340
329
|
refreshGatt: 'OnConnected',
|
|
341
330
|
};
|
|
331
|
+
const fallbackConnectOptions = {
|
|
332
|
+
timeout: BLE_NATIVE_CONNECT_TIMEOUT_MS,
|
|
333
|
+
};
|
|
334
|
+
const BLE_CONNECT_TIMEOUT_MS = BLE_NATIVE_CONNECT_TIMEOUT_MS * 2 + 2000;
|
|
335
|
+
const BLE_GATT_SETUP_TIMEOUT_MS = 10000;
|
|
336
|
+
const PROTOCOL_REPROBE_FALLBACK_ATTEMPTS = 3;
|
|
337
|
+
const BLE_CONNECT_TIMEOUT_MANAGER_RESET_THRESHOLD = 2;
|
|
338
|
+
const CONNECT_TIMEOUT_MESSAGE = 'BLE connect timeout after';
|
|
339
|
+
const isConnectTimeoutError = (error) => (error === null || error === void 0 ? void 0 : error.errorCode) === hdShared.HardwareErrorCode.BleConnectedError &&
|
|
340
|
+
typeof (error === null || error === void 0 ? void 0 : error.message) === 'string' &&
|
|
341
|
+
error.message.startsWith(CONNECT_TIMEOUT_MESSAGE);
|
|
342
|
+
const isNativeOperationTimeoutError = (error) => (error === null || error === void 0 ? void 0 : error.errorCode) === reactNativeBlePlx.BleErrorCode.OperationTimedOut;
|
|
342
343
|
const tryToGetConfiguration = (device) => {
|
|
343
344
|
if (!device || !device.serviceUUIDs)
|
|
344
345
|
return null;
|
|
@@ -350,23 +351,25 @@ const tryToGetConfiguration = (device) => {
|
|
|
350
351
|
return null;
|
|
351
352
|
return infos;
|
|
352
353
|
};
|
|
353
|
-
const
|
|
354
|
-
if (reactNative.Platform.OS !== 'android')
|
|
354
|
+
const requestNegotiatedMtu = (device, stage, attempt) => __awaiter(void 0, void 0, void 0, function* () {
|
|
355
|
+
if (reactNative.Platform.OS !== 'ios' && reactNative.Platform.OS !== 'android')
|
|
355
356
|
return device;
|
|
356
357
|
try {
|
|
357
|
-
const mtuDevice = yield device.requestMTU(
|
|
358
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] MTU configured', {
|
|
359
|
-
deviceId: device.id,
|
|
360
|
-
requested: ANDROID_REQUEST_MTU,
|
|
361
|
-
actual: mtuDevice.mtu,
|
|
362
|
-
});
|
|
358
|
+
const mtuDevice = yield device.requestMTU(getRequestedBleMtu());
|
|
363
359
|
return mtuDevice;
|
|
364
360
|
}
|
|
365
361
|
catch (error) {
|
|
366
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport]
|
|
362
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] MTU refresh failed, continuing with current value', {
|
|
363
|
+
platform: reactNative.Platform.OS,
|
|
364
|
+
stage,
|
|
365
|
+
attempt,
|
|
366
|
+
actual: device.mtu,
|
|
367
|
+
error: error instanceof Error ? error.message : String(error),
|
|
368
|
+
});
|
|
367
369
|
return device;
|
|
368
370
|
}
|
|
369
371
|
});
|
|
372
|
+
const resolveNegotiatedMtu = (device) => requestNegotiatedMtu(device, 'connected', 0);
|
|
370
373
|
function remapError(error) {
|
|
371
374
|
var _a;
|
|
372
375
|
if (error instanceof reactNativeBlePlx.BleError) {
|
|
@@ -393,9 +396,15 @@ class ReactNativeBleTransport {
|
|
|
393
396
|
this.stopped = false;
|
|
394
397
|
this.scanTimeout = DEVICE_SCAN_TIMEOUT_MS;
|
|
395
398
|
this.runPromise = null;
|
|
399
|
+
this.runPromiseDeviceId = null;
|
|
396
400
|
this.firmwareUploadWriteRecoveryIds = new Set();
|
|
397
401
|
this.deviceProtocol = new Map();
|
|
402
|
+
this.probingProtocols = new Map();
|
|
403
|
+
this.writeTimeoutCounts = new Map();
|
|
404
|
+
this.connectionSetupTimeoutCounts = new Map();
|
|
398
405
|
this.deviceProtocolHints = new Map();
|
|
406
|
+
this.sessionProtocols = new Map();
|
|
407
|
+
this.protocolReprobeFailures = new Map();
|
|
399
408
|
this.protocolV2Assemblers = new Map();
|
|
400
409
|
this.protocolV2FrameQueues = new Map();
|
|
401
410
|
this.protocolV2FramePromises = new Map();
|
|
@@ -416,12 +425,17 @@ class ReactNativeBleTransport {
|
|
|
416
425
|
this.rejectProtocolV2Frames(uuid, new Error(reason));
|
|
417
426
|
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V2 link invalidated:', uuid, reason);
|
|
418
427
|
if (reason.startsWith('Protocol V2 link-fatal error:')) {
|
|
419
|
-
yield this.
|
|
428
|
+
yield this.releaseNative(uuid, true);
|
|
420
429
|
}
|
|
421
430
|
}),
|
|
422
431
|
});
|
|
423
432
|
this.monitorTokens = new Map();
|
|
433
|
+
this.disconnectEventTokens = new Map();
|
|
434
|
+
this.protocolV2HighVolumeLogSignatures = new Map();
|
|
435
|
+
this.androidHighPriorityDevices = new Set();
|
|
436
|
+
this.androidPriorityResetTimers = new Map();
|
|
424
437
|
this.nextMonitorToken = 1;
|
|
438
|
+
this.lifecycleOperations = new Map();
|
|
425
439
|
this.scanTimeout = (_a = options.scanTimeout) !== null && _a !== void 0 ? _a : DEVICE_SCAN_TIMEOUT_MS;
|
|
426
440
|
}
|
|
427
441
|
init(logger, emitter) {
|
|
@@ -434,10 +448,18 @@ class ReactNativeBleTransport {
|
|
|
434
448
|
this._messages = messages;
|
|
435
449
|
}
|
|
436
450
|
configureProtocolV2(signedData) {
|
|
451
|
+
const configuration = typeof signedData === 'string' ? signedData : JSON.stringify(signedData);
|
|
452
|
+
if (this.protocolV2SchemaConfiguration === configuration) {
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
455
|
+
const isReconfiguration = this.protocolV2SchemaConfiguration !== undefined;
|
|
437
456
|
this._messagesV2 = parseConfigure(signedData);
|
|
438
|
-
this.
|
|
439
|
-
|
|
440
|
-
.
|
|
457
|
+
this.protocolV2SchemaConfiguration = configuration;
|
|
458
|
+
if (isReconfiguration) {
|
|
459
|
+
this.protocolV2Links
|
|
460
|
+
.invalidateAllLinks('Protocol V2 schema reconfigured')
|
|
461
|
+
.catch(error => Log === null || Log === void 0 ? void 0 : Log.debug('Protocol V2 schema link cleanup failed:', error));
|
|
462
|
+
}
|
|
441
463
|
}
|
|
442
464
|
listen() {
|
|
443
465
|
}
|
|
@@ -448,7 +470,6 @@ class ReactNativeBleTransport {
|
|
|
448
470
|
return Promise.resolve(this.blePlxManager);
|
|
449
471
|
}
|
|
450
472
|
resolveCharacteristics(device) {
|
|
451
|
-
var _a, _b, _c, _d;
|
|
452
473
|
return __awaiter(this, void 0, void 0, function* () {
|
|
453
474
|
yield device.discoverAllServicesAndCharacteristics();
|
|
454
475
|
let infos = tryToGetConfiguration(device);
|
|
@@ -465,19 +486,11 @@ class ReactNativeBleTransport {
|
|
|
465
486
|
}
|
|
466
487
|
}
|
|
467
488
|
}
|
|
468
|
-
let fallbackServiceUuid;
|
|
469
489
|
if (!infos) {
|
|
470
490
|
const services = yield device.services();
|
|
471
491
|
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Known OneKey service UUID not found, discovered services:', services === null || services === void 0 ? void 0 : services.map(service => service.uuid));
|
|
472
|
-
const knownService = services.find(service => getInfosForServiceUuid(service.uuid, 'classic'));
|
|
473
|
-
const fallbackService = (_a = knownService !== null && knownService !== void 0 ? knownService : services.find(service => !isGenericBleService(service.uuid))) !== null && _a !== void 0 ? _a : services[0];
|
|
474
|
-
if (fallbackService) {
|
|
475
|
-
fallbackServiceUuid = fallbackService.uuid;
|
|
476
|
-
characteristics = yield device.characteristicsForService(fallbackService.uuid);
|
|
477
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Using fallback BLE service:', fallbackService.uuid);
|
|
478
|
-
}
|
|
479
492
|
}
|
|
480
|
-
if (!infos
|
|
493
|
+
if (!infos) {
|
|
481
494
|
try {
|
|
482
495
|
Log === null || Log === void 0 ? void 0 : Log.debug('cancel connection when service not found');
|
|
483
496
|
yield device.cancelConnection();
|
|
@@ -487,9 +500,7 @@ class ReactNativeBleTransport {
|
|
|
487
500
|
}
|
|
488
501
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleServiceNotFound);
|
|
489
502
|
}
|
|
490
|
-
const serviceUuid
|
|
491
|
-
const writeUuid = (_c = infos === null || infos === void 0 ? void 0 : infos.writeUuid) !== null && _c !== void 0 ? _c : '00000002-0000-1000-8000-00805f9b34fb';
|
|
492
|
-
const notifyUuid = (_d = infos === null || infos === void 0 ? void 0 : infos.notifyUuid) !== null && _d !== void 0 ? _d : '00000003-0000-1000-8000-00805f9b34fb';
|
|
503
|
+
const { serviceUuid, writeUuid, notifyUuid } = infos;
|
|
493
504
|
if (!serviceUuid) {
|
|
494
505
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleServiceNotFound);
|
|
495
506
|
}
|
|
@@ -530,8 +541,8 @@ class ReactNativeBleTransport {
|
|
|
530
541
|
attachDisconnectSubscription(transport, device, uuid) {
|
|
531
542
|
var _a;
|
|
532
543
|
(_a = transport.disconnectSubscription) === null || _a === void 0 ? void 0 : _a.remove();
|
|
544
|
+
const { monitorToken } = transport;
|
|
533
545
|
transport.disconnectSubscription = device.onDisconnected(() => {
|
|
534
|
-
var _a;
|
|
535
546
|
if (this.firmwareUploadWriteRecoveryIds.has(uuid)) {
|
|
536
547
|
Log === null || Log === void 0 ? void 0 : Log.debug('device disconnect ignored during FirmwareUpload write recovery: ', uuid);
|
|
537
548
|
return;
|
|
@@ -540,17 +551,16 @@ class ReactNativeBleTransport {
|
|
|
540
551
|
Log === null || Log === void 0 ? void 0 : Log.debug('device disconnect ignored for stale transport: ', device === null || device === void 0 ? void 0 : device.id);
|
|
541
552
|
return;
|
|
542
553
|
}
|
|
554
|
+
if (this.monitorTokens.get(uuid) !== monitorToken) {
|
|
555
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('device disconnect ignored for stale generation: ', device === null || device === void 0 ? void 0 : device.id);
|
|
556
|
+
return;
|
|
557
|
+
}
|
|
543
558
|
try {
|
|
544
559
|
Log === null || Log === void 0 ? void 0 : Log.debug('device disconnect: ', device === null || device === void 0 ? void 0 : device.id);
|
|
545
|
-
(
|
|
546
|
-
|
|
547
|
-
id: device === null || device === void 0 ? void 0 : device.id,
|
|
548
|
-
connectId: device === null || device === void 0 ? void 0 : device.id,
|
|
549
|
-
});
|
|
550
|
-
if (this.runPromise) {
|
|
560
|
+
this.emitDeviceDisconnect(uuid, device === null || device === void 0 ? void 0 : device.name, monitorToken);
|
|
561
|
+
if (this.runPromise && this.runPromiseDeviceId === uuid) {
|
|
551
562
|
const error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleConnectedError);
|
|
552
563
|
this.runPromise.reject(error);
|
|
553
|
-
this.rejectAllProtocolV2Frames(error);
|
|
554
564
|
}
|
|
555
565
|
}
|
|
556
566
|
catch (e) {
|
|
@@ -561,6 +571,22 @@ class ReactNativeBleTransport {
|
|
|
561
571
|
}
|
|
562
572
|
});
|
|
563
573
|
}
|
|
574
|
+
emitDeviceDisconnect(uuid, name, token) {
|
|
575
|
+
var _a;
|
|
576
|
+
if (token === undefined || this.disconnectEventTokens.get(uuid) === token) {
|
|
577
|
+
return;
|
|
578
|
+
}
|
|
579
|
+
if (this.monitorTokens.get(uuid) !== token) {
|
|
580
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('device disconnect event ignored for stale generation: ', uuid);
|
|
581
|
+
return;
|
|
582
|
+
}
|
|
583
|
+
this.disconnectEventTokens.set(uuid, token);
|
|
584
|
+
(_a = this.emitter) === null || _a === void 0 ? void 0 : _a.emit(transport.TRANSPORT_EVENT.DEVICE_DISCONNECT, {
|
|
585
|
+
name,
|
|
586
|
+
id: uuid,
|
|
587
|
+
connectId: uuid,
|
|
588
|
+
});
|
|
589
|
+
}
|
|
564
590
|
reconnectFirmwareUploadTransport(uuid, transport) {
|
|
565
591
|
var _a, _b;
|
|
566
592
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -574,19 +600,19 @@ class ReactNativeBleTransport {
|
|
|
574
600
|
const isConnected = yield device.isConnected().catch(() => false);
|
|
575
601
|
if (!isConnected) {
|
|
576
602
|
try {
|
|
577
|
-
device = yield device.connect(connectOptions);
|
|
603
|
+
device = yield this.connectWithTimeout(uuid, () => device.connect(connectOptions));
|
|
578
604
|
}
|
|
579
605
|
catch (e) {
|
|
580
606
|
if (e.errorCode === reactNativeBlePlx.BleErrorCode.DeviceMTUChangeFailed ||
|
|
581
607
|
e.errorCode === reactNativeBlePlx.BleErrorCode.OperationCancelled) {
|
|
582
|
-
device = yield device.connect();
|
|
608
|
+
device = yield this.connectWithTimeout(uuid, () => device.connect());
|
|
583
609
|
}
|
|
584
610
|
else if (e.errorCode !== reactNativeBlePlx.BleErrorCode.DeviceAlreadyConnected) {
|
|
585
611
|
throw e;
|
|
586
612
|
}
|
|
587
613
|
}
|
|
588
614
|
}
|
|
589
|
-
const { writeCharacteristic, notifyCharacteristic } = yield this.
|
|
615
|
+
const { writeCharacteristic, notifyCharacteristic } = yield this.resolveCharacteristicsWithTimeout(uuid, device);
|
|
590
616
|
transport.device = device;
|
|
591
617
|
transport.writeCharacteristic = writeCharacteristic;
|
|
592
618
|
transport.notifyCharacteristic = notifyCharacteristic;
|
|
@@ -634,7 +660,7 @@ class ReactNativeBleTransport {
|
|
|
634
660
|
allowDuplicates: true,
|
|
635
661
|
scanMode: reactNativeBlePlx.ScanMode.LowLatency,
|
|
636
662
|
}, (error, device) => {
|
|
637
|
-
var _a, _b
|
|
663
|
+
var _a, _b;
|
|
638
664
|
if (error) {
|
|
639
665
|
Log === null || Log === void 0 ? void 0 : Log.debug('ble scan error: ', error);
|
|
640
666
|
if ([reactNativeBlePlx.BleErrorCode.BluetoothPoweredOff, reactNativeBlePlx.BleErrorCode.BluetoothInUnknownState].includes(error.errorCode)) {
|
|
@@ -655,9 +681,14 @@ class ReactNativeBleTransport {
|
|
|
655
681
|
return;
|
|
656
682
|
}
|
|
657
683
|
const displayName = getDeviceDisplayName(device);
|
|
658
|
-
const
|
|
659
|
-
|
|
660
|
-
|
|
684
|
+
const isUnnamedIOSPeripheral = reactNative.Platform.OS === 'ios' && !(displayName === null || displayName === void 0 ? void 0 : displayName.trim());
|
|
685
|
+
const isOneKey = !isUnnamedIOSPeripheral &&
|
|
686
|
+
hdShared.isOnekeyBluetoothDevice({
|
|
687
|
+
id: device === null || device === void 0 ? void 0 : device.id,
|
|
688
|
+
name: device === null || device === void 0 ? void 0 : device.name,
|
|
689
|
+
localName: device === null || device === void 0 ? void 0 : device.localName,
|
|
690
|
+
serviceUuids: (_b = device === null || device === void 0 ? void 0 : device.serviceUUIDs) !== null && _b !== void 0 ? _b : getBluetoothServiceUuids(),
|
|
691
|
+
});
|
|
661
692
|
if (isOneKey) {
|
|
662
693
|
addDevice(device);
|
|
663
694
|
}
|
|
@@ -672,10 +703,15 @@ class ReactNativeBleTransport {
|
|
|
672
703
|
});
|
|
673
704
|
getConnectedDeviceIds(reactNative.Platform.OS === 'ios' ? getBluetoothServiceUuids() : []).then(devices => {
|
|
674
705
|
for (const device of devices) {
|
|
675
|
-
const
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
if (
|
|
706
|
+
const localName = 'localName' in device && typeof device.localName === 'string'
|
|
707
|
+
? device.localName
|
|
708
|
+
: null;
|
|
709
|
+
if (hdShared.isOnekeyBluetoothDevice({
|
|
710
|
+
id: device.id,
|
|
711
|
+
name: device.name,
|
|
712
|
+
localName,
|
|
713
|
+
serviceUuids: device.serviceUUIDs,
|
|
714
|
+
})) {
|
|
679
715
|
Log === null || Log === void 0 ? void 0 : Log.debug('search connected peripheral: ', device.id);
|
|
680
716
|
addDevice(device);
|
|
681
717
|
}
|
|
@@ -705,13 +741,70 @@ class ReactNativeBleTransport {
|
|
|
705
741
|
}));
|
|
706
742
|
});
|
|
707
743
|
}
|
|
744
|
+
installTransportForAcquire(uuid, device, characteristics) {
|
|
745
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
746
|
+
const { writeCharacteristic, notifyCharacteristic } = characteristics !== null && characteristics !== void 0 ? characteristics : (yield this.resolveCharacteristicsWithTimeout(uuid, device));
|
|
747
|
+
const transport$1 = new BleTransport(device, writeCharacteristic, notifyCharacteristic);
|
|
748
|
+
transport$1.mtuSize = typeof device.mtu === 'number' ? device.mtu : undefined;
|
|
749
|
+
const monitorToken = this.nextMonitorToken;
|
|
750
|
+
this.nextMonitorToken += 1;
|
|
751
|
+
const notifyTransactionId = `${uuid}:notify:${monitorToken}`;
|
|
752
|
+
transport$1.monitorToken = monitorToken;
|
|
753
|
+
transport$1.notifyTransactionId = notifyTransactionId;
|
|
754
|
+
this.monitorTokens.set(uuid, monitorToken);
|
|
755
|
+
transport$1.notifySubscription = this._monitorCharacteristic(transport$1.notifyCharacteristic, uuid, monitorToken, notifyTransactionId);
|
|
756
|
+
transportCache[uuid] = transport$1;
|
|
757
|
+
this.protocolV2HighVolumeLogSignatures.set(uuid, new Set());
|
|
758
|
+
this.protocolV2Assemblers.set(uuid, new transport.ProtocolV2FrameAssembler(transport.PROTOCOL_V2_BLE_FRAME_MAX_BYTES));
|
|
759
|
+
if (reactNative.Platform.OS === 'ios') {
|
|
760
|
+
yield new Promise(resolve => {
|
|
761
|
+
setTimeout(resolve, IOS_NOTIFY_READY_DELAY_MS);
|
|
762
|
+
});
|
|
763
|
+
}
|
|
764
|
+
else if (reactNative.Platform.OS === 'android') {
|
|
765
|
+
yield delay(ANDROID_NOTIFY_READY_DELAY_MS);
|
|
766
|
+
}
|
|
767
|
+
const initialMtu = transport$1.mtuSize;
|
|
768
|
+
let refreshAttempts = 0;
|
|
769
|
+
if ((reactNative.Platform.OS === 'ios' || reactNative.Platform.OS === 'android') &&
|
|
770
|
+
shouldRefreshNegotiatedMtu(transport$1.mtuSize)) {
|
|
771
|
+
refreshAttempts += 1;
|
|
772
|
+
let refreshedDevice = yield requestNegotiatedMtu(transport$1.device, 'servicesAndNotifyReady', 1);
|
|
773
|
+
transport$1.device = refreshedDevice;
|
|
774
|
+
transport$1.mtuSize =
|
|
775
|
+
typeof refreshedDevice.mtu === 'number' ? refreshedDevice.mtu : transport$1.mtuSize;
|
|
776
|
+
if (shouldRefreshNegotiatedMtu(transport$1.mtuSize)) {
|
|
777
|
+
yield delay(BLE_MTU_REFRESH_RETRY_DELAY_MS);
|
|
778
|
+
refreshAttempts += 1;
|
|
779
|
+
refreshedDevice = yield requestNegotiatedMtu(transport$1.device, 'servicesAndNotifyReady', 2);
|
|
780
|
+
transport$1.device = refreshedDevice;
|
|
781
|
+
transport$1.mtuSize =
|
|
782
|
+
typeof refreshedDevice.mtu === 'number' ? refreshedDevice.mtu : transport$1.mtuSize;
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] BLE MTU ready', {
|
|
786
|
+
platform: reactNative.Platform.OS,
|
|
787
|
+
requested: getRequestedBleMtu(),
|
|
788
|
+
initial: initialMtu,
|
|
789
|
+
actual: transport$1.mtuSize,
|
|
790
|
+
refreshAttempts,
|
|
791
|
+
});
|
|
792
|
+
return transport$1;
|
|
793
|
+
});
|
|
794
|
+
}
|
|
708
795
|
acquire(input) {
|
|
709
|
-
var _a, _b;
|
|
710
796
|
return __awaiter(this, void 0, void 0, function* () {
|
|
711
|
-
const { uuid
|
|
797
|
+
const { uuid } = input;
|
|
712
798
|
if (!uuid) {
|
|
713
799
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleRequiredUUID);
|
|
714
800
|
}
|
|
801
|
+
return this.runLifecycleOperation(uuid, () => this.acquireUnlocked(input));
|
|
802
|
+
});
|
|
803
|
+
}
|
|
804
|
+
acquireUnlocked(input) {
|
|
805
|
+
var _a, _b;
|
|
806
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
807
|
+
const { uuid, forceCleanRunPromise, expectedProtocol } = input;
|
|
715
808
|
const cachedTransport = transportCache[uuid];
|
|
716
809
|
if (cachedTransport) {
|
|
717
810
|
const cachedProtocol = this.deviceProtocol.get(uuid);
|
|
@@ -723,14 +816,14 @@ class ReactNativeBleTransport {
|
|
|
723
816
|
return { uuid, protocolType: cachedProtocol };
|
|
724
817
|
}
|
|
725
818
|
Log === null || Log === void 0 ? void 0 : Log.debug('transport not reusable, will release: ', uuid);
|
|
726
|
-
yield this.
|
|
819
|
+
yield this.releaseUnlocked(uuid, true);
|
|
727
820
|
}
|
|
728
821
|
let device = null;
|
|
729
822
|
if (forceCleanRunPromise && this.runPromise) {
|
|
730
823
|
const error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleForceCleanRunPromise);
|
|
731
824
|
this.runPromise.reject(error);
|
|
732
|
-
this.rejectAllProtocolV2Frames(error);
|
|
733
825
|
this.runPromise = null;
|
|
826
|
+
this.runPromiseDeviceId = null;
|
|
734
827
|
Log === null || Log === void 0 ? void 0 : Log.debug('Force clean Bluetooth run promise, forceCleanRunPromise: ', forceCleanRunPromise);
|
|
735
828
|
}
|
|
736
829
|
const blePlxManager = yield this.getPlxManager();
|
|
@@ -763,14 +856,17 @@ class ReactNativeBleTransport {
|
|
|
763
856
|
if (!device) {
|
|
764
857
|
Log === null || Log === void 0 ? void 0 : Log.debug('try to connect to device: ', uuid);
|
|
765
858
|
try {
|
|
766
|
-
device = yield blePlxManager.connectToDevice(uuid, connectOptions);
|
|
859
|
+
device = yield this.connectWithTimeout(uuid, () => blePlxManager.connectToDevice(uuid, connectOptions));
|
|
767
860
|
}
|
|
768
861
|
catch (e) {
|
|
769
862
|
Log === null || Log === void 0 ? void 0 : Log.debug('try to connect to device has error: ', e);
|
|
863
|
+
if (isConnectTimeoutError(e)) {
|
|
864
|
+
throw e;
|
|
865
|
+
}
|
|
770
866
|
if (e.errorCode === reactNativeBlePlx.BleErrorCode.DeviceMTUChangeFailed ||
|
|
771
867
|
e.errorCode === reactNativeBlePlx.BleErrorCode.OperationCancelled) {
|
|
772
868
|
Log === null || Log === void 0 ? void 0 : Log.debug('first try to reconnect without params');
|
|
773
|
-
device = yield blePlxManager.connectToDevice(uuid);
|
|
869
|
+
device = yield this.connectWithTimeout(uuid, () => blePlxManager.connectToDevice(uuid, fallbackConnectOptions));
|
|
774
870
|
}
|
|
775
871
|
else if (e.errorCode === reactNativeBlePlx.BleErrorCode.DeviceAlreadyConnected) {
|
|
776
872
|
Log === null || Log === void 0 ? void 0 : Log.debug('device already connected');
|
|
@@ -786,23 +882,27 @@ class ReactNativeBleTransport {
|
|
|
786
882
|
}
|
|
787
883
|
if (!(yield device.isConnected())) {
|
|
788
884
|
Log === null || Log === void 0 ? void 0 : Log.debug('not connected, try to connect to device: ', uuid);
|
|
885
|
+
const disconnectedDevice = device;
|
|
789
886
|
try {
|
|
790
|
-
device = yield
|
|
887
|
+
device = yield this.connectWithTimeout(uuid, () => disconnectedDevice.connect(connectOptions));
|
|
791
888
|
}
|
|
792
889
|
catch (e) {
|
|
793
890
|
Log === null || Log === void 0 ? void 0 : Log.debug('not connected, try to connect to device has error: ', e);
|
|
891
|
+
if (isConnectTimeoutError(e)) {
|
|
892
|
+
throw e;
|
|
893
|
+
}
|
|
794
894
|
if (e.errorCode === reactNativeBlePlx.BleErrorCode.DeviceMTUChangeFailed ||
|
|
795
895
|
e.errorCode === reactNativeBlePlx.BleErrorCode.OperationCancelled) {
|
|
796
896
|
Log === null || Log === void 0 ? void 0 : Log.debug('second try to reconnect without params');
|
|
797
897
|
try {
|
|
798
|
-
device = yield
|
|
898
|
+
device = yield this.connectWithTimeout(uuid, () => disconnectedDevice.connect(fallbackConnectOptions));
|
|
799
899
|
}
|
|
800
900
|
catch (e) {
|
|
801
901
|
Log === null || Log === void 0 ? void 0 : Log.debug('last try to reconnect error: ', e);
|
|
802
902
|
if (e.errorCode === reactNativeBlePlx.BleErrorCode.OperationCancelled) {
|
|
803
903
|
Log === null || Log === void 0 ? void 0 : Log.debug('last try to reconnect');
|
|
804
|
-
yield
|
|
805
|
-
device = yield
|
|
904
|
+
yield disconnectedDevice.cancelConnection();
|
|
905
|
+
device = yield this.connectWithTimeout(uuid, () => disconnectedDevice.connect(fallbackConnectOptions));
|
|
806
906
|
}
|
|
807
907
|
}
|
|
808
908
|
}
|
|
@@ -811,44 +911,35 @@ class ReactNativeBleTransport {
|
|
|
811
911
|
}
|
|
812
912
|
}
|
|
813
913
|
}
|
|
814
|
-
device = yield
|
|
815
|
-
const
|
|
914
|
+
device = yield resolveNegotiatedMtu(device);
|
|
915
|
+
const acquiredDevice = device;
|
|
916
|
+
const { writeCharacteristic, notifyCharacteristic } = yield this.resolveCharacteristicsWithTimeout(uuid, acquiredDevice);
|
|
816
917
|
const protocolHint = expectedProtocol
|
|
817
918
|
? undefined
|
|
818
|
-
: (_a = this.deviceProtocolHints.get(uuid)) !== null &&
|
|
819
|
-
yield this.
|
|
919
|
+
: (_b = (_a = input.protocolHint) !== null && _a !== void 0 ? _a : this.deviceProtocolHints.get(uuid)) !== null && _b !== void 0 ? _b : inferProtocolHintFromDeviceName(getDeviceDisplayName(acquiredDevice));
|
|
920
|
+
yield this.releaseUnlocked(uuid, true);
|
|
820
921
|
if (protocolHint) {
|
|
821
922
|
this.deviceProtocolHints.set(uuid, protocolHint);
|
|
822
923
|
}
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
}
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
yield new Promise(resolve => {
|
|
838
|
-
setTimeout(resolve, IOS_NOTIFY_READY_DELAY_MS);
|
|
839
|
-
});
|
|
924
|
+
yield this.installTransportForAcquire(uuid, acquiredDevice, {
|
|
925
|
+
writeCharacteristic,
|
|
926
|
+
notifyCharacteristic,
|
|
927
|
+
});
|
|
928
|
+
try {
|
|
929
|
+
const protocolType = yield this.detectProtocol(uuid, expectedProtocol, protocolHint, () => __awaiter(this, void 0, void 0, function* () {
|
|
930
|
+
yield this.installTransportForAcquire(uuid, acquiredDevice);
|
|
931
|
+
}));
|
|
932
|
+
const currentTransport = transportCache[uuid];
|
|
933
|
+
if (!currentTransport) {
|
|
934
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.TransportNotFound);
|
|
935
|
+
}
|
|
936
|
+
this.attachDisconnectSubscription(currentTransport, currentTransport.device, uuid);
|
|
937
|
+
return { uuid, protocolType };
|
|
840
938
|
}
|
|
841
|
-
|
|
842
|
-
yield
|
|
939
|
+
catch (error) {
|
|
940
|
+
yield this.releaseUnlocked(uuid, true);
|
|
941
|
+
throw error;
|
|
843
942
|
}
|
|
844
|
-
const protocolType = yield this.detectProtocol(uuid, expectedProtocol, protocolHint);
|
|
845
|
-
(_b = this.emitter) === null || _b === void 0 ? void 0 : _b.emit('device-connect', {
|
|
846
|
-
name: device.name,
|
|
847
|
-
id: device.id,
|
|
848
|
-
connectId: device.id,
|
|
849
|
-
});
|
|
850
|
-
this.attachDisconnectSubscription(transport$1, device, uuid);
|
|
851
|
-
return { uuid, protocolType };
|
|
852
943
|
});
|
|
853
944
|
}
|
|
854
945
|
_monitorCharacteristic(characteristic, uuid, monitorToken, notifyTransactionId) {
|
|
@@ -867,7 +958,7 @@ class ReactNativeBleTransport {
|
|
|
867
958
|
Log === null || Log === void 0 ? void 0 : Log.debug('monitor error ignored for stale transport: ', uuid, notifyTransactionId);
|
|
868
959
|
return;
|
|
869
960
|
}
|
|
870
|
-
if (this.
|
|
961
|
+
if (this.getActiveProtocol(uuid) === 'V2') {
|
|
871
962
|
let errorCode = hdShared.HardwareErrorCode.BleCharacteristicNotifyError;
|
|
872
963
|
if ((_a = error.reason) === null || _a === void 0 ? void 0 : _a.includes('The connection has timed out unexpectedly')) {
|
|
873
964
|
errorCode = hdShared.HardwareErrorCode.BleTimeoutError;
|
|
@@ -885,7 +976,7 @@ class ReactNativeBleTransport {
|
|
|
885
976
|
this.rejectProtocolV2Frames(uuid, hdShared.ERRORS.TypedError(errorCode));
|
|
886
977
|
return;
|
|
887
978
|
}
|
|
888
|
-
if (this.runPromise) {
|
|
979
|
+
if (this.runPromise && this.runPromiseDeviceId === uuid) {
|
|
889
980
|
let ERROR = hdShared.HardwareErrorCode.BleCharacteristicNotifyError;
|
|
890
981
|
if ((_h = error.reason) === null || _h === void 0 ? void 0 : _h.includes('The connection has timed out unexpectedly')) {
|
|
891
982
|
ERROR = hdShared.HardwareErrorCode.BleTimeoutError;
|
|
@@ -900,13 +991,11 @@ class ReactNativeBleTransport {
|
|
|
900
991
|
((_p = error.reason) === null || _p === void 0 ? void 0 : _p.includes('notify change failed for device'))) {
|
|
901
992
|
const notifyError = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleCharacteristicNotifyChangeFailure);
|
|
902
993
|
this.runPromise.reject(notifyError);
|
|
903
|
-
this.rejectAllProtocolV2Frames(notifyError);
|
|
904
994
|
Log === null || Log === void 0 ? void 0 : Log.debug(`${hdShared.HardwareErrorCode.BleCharacteristicNotifyChangeFailure} ${error.message} ${error.reason}`);
|
|
905
995
|
return;
|
|
906
996
|
}
|
|
907
997
|
const notifyError = hdShared.ERRORS.TypedError(ERROR);
|
|
908
998
|
this.runPromise.reject(notifyError);
|
|
909
|
-
this.rejectAllProtocolV2Frames(notifyError);
|
|
910
999
|
Log === null || Log === void 0 ? void 0 : Log.debug(': monitor notify error, and has unreleased Promise', Error);
|
|
911
1000
|
}
|
|
912
1001
|
return;
|
|
@@ -920,7 +1009,7 @@ class ReactNativeBleTransport {
|
|
|
920
1009
|
}
|
|
921
1010
|
try {
|
|
922
1011
|
const data = buffer.Buffer.from(c.value, 'base64');
|
|
923
|
-
const protocol = this.
|
|
1012
|
+
const protocol = this.getActiveProtocol(uuid);
|
|
924
1013
|
if (!protocol) {
|
|
925
1014
|
Log === null || Log === void 0 ? void 0 : Log.debug('monitor data ignored before protocol detection: ', uuid);
|
|
926
1015
|
return;
|
|
@@ -940,16 +1029,18 @@ class ReactNativeBleTransport {
|
|
|
940
1029
|
const value = buffer.Buffer.from(buffer$1);
|
|
941
1030
|
bufferLength = 0;
|
|
942
1031
|
buffer$1 = [];
|
|
943
|
-
(
|
|
1032
|
+
if (this.runPromiseDeviceId === uuid) {
|
|
1033
|
+
(_q = this.runPromise) === null || _q === void 0 ? void 0 : _q.resolve(value.toString('hex'));
|
|
1034
|
+
}
|
|
944
1035
|
}
|
|
945
1036
|
}
|
|
946
1037
|
catch (error) {
|
|
947
1038
|
Log === null || Log === void 0 ? void 0 : Log.debug('monitor data error: ', error);
|
|
948
1039
|
const notifyError = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleWriteCharacteristicError);
|
|
949
|
-
if (this.
|
|
1040
|
+
if (this.getActiveProtocol(uuid) === 'V2') {
|
|
950
1041
|
this.rejectProtocolV2Frames(uuid, notifyError);
|
|
951
1042
|
}
|
|
952
|
-
else {
|
|
1043
|
+
else if (this.runPromiseDeviceId === uuid) {
|
|
953
1044
|
(_r = this.runPromise) === null || _r === void 0 ? void 0 : _r.reject(notifyError);
|
|
954
1045
|
}
|
|
955
1046
|
}
|
|
@@ -957,15 +1048,27 @@ class ReactNativeBleTransport {
|
|
|
957
1048
|
return subscription;
|
|
958
1049
|
}
|
|
959
1050
|
release(uuid, onclose = false) {
|
|
960
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
961
1051
|
return __awaiter(this, void 0, void 0, function* () {
|
|
962
|
-
|
|
1052
|
+
return this.runLifecycleOperation(uuid, () => this.releaseUnlocked(uuid, onclose));
|
|
1053
|
+
});
|
|
1054
|
+
}
|
|
1055
|
+
releaseUnlocked(uuid, onclose = false) {
|
|
1056
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
963
1057
|
yield this.protocolV2Links.invalidateLink(uuid, 'React Native BLE transport released');
|
|
964
|
-
|
|
1058
|
+
return this.releaseNative(uuid, onclose);
|
|
1059
|
+
});
|
|
1060
|
+
}
|
|
1061
|
+
releaseNative(uuid, onclose = false) {
|
|
1062
|
+
var _a, _b, _c, _d, _e;
|
|
1063
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1064
|
+
const transport = transportCache[uuid];
|
|
1065
|
+
const manager = this.blePlxManager;
|
|
1066
|
+
if (this.runPromise && this.runPromiseDeviceId === uuid) {
|
|
965
1067
|
const error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleForceCleanRunPromise);
|
|
966
1068
|
this.runPromise.reject(error);
|
|
967
1069
|
this.runPromise = null;
|
|
968
|
-
this.
|
|
1070
|
+
this.runPromiseDeviceId = null;
|
|
1071
|
+
this.rejectProtocolV2Frames(uuid, error);
|
|
969
1072
|
}
|
|
970
1073
|
else {
|
|
971
1074
|
this.resetProtocolV2Frames(uuid);
|
|
@@ -985,31 +1088,37 @@ class ReactNativeBleTransport {
|
|
|
985
1088
|
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
1089
|
(_d = transport.notifySubscription) === null || _d === void 0 ? void 0 : _d.remove();
|
|
987
1090
|
transport.notifySubscription = undefined;
|
|
988
|
-
if (transport
|
|
989
|
-
|
|
990
|
-
yield ((_e = this.blePlxManager) === null || _e === void 0 ? void 0 : _e.cancelTransaction(transport.notifyTransactionId));
|
|
991
|
-
}
|
|
992
|
-
catch (e) {
|
|
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);
|
|
994
|
-
}
|
|
1091
|
+
if (transportCache[uuid] === transport) {
|
|
1092
|
+
delete transportCache[uuid];
|
|
995
1093
|
}
|
|
996
|
-
delete transportCache[uuid];
|
|
997
1094
|
}
|
|
1095
|
+
this.protocolV2HighVolumeLogSignatures.delete(uuid);
|
|
998
1096
|
this.deviceProtocol.delete(uuid);
|
|
999
|
-
|
|
1097
|
+
this.probingProtocols.delete(uuid);
|
|
1098
|
+
(_e = this.protocolV2Assemblers.get(uuid)) === null || _e === void 0 ? void 0 : _e.reset();
|
|
1000
1099
|
this.protocolV2Assemblers.delete(uuid);
|
|
1001
1100
|
this.resetProtocolV2Frames(uuid);
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1101
|
+
yield this.runNativeTeardown(uuid, manager, () => __awaiter(this, void 0, void 0, function* () {
|
|
1102
|
+
const operations = [
|
|
1103
|
+
this.runBestEffortNativeOperation('release: restore connection priority', () => this.restoreAndroidConnectionPriority(uuid, transport)),
|
|
1104
|
+
];
|
|
1105
|
+
if ((transport === null || transport === void 0 ? void 0 : transport.notifyTransactionId) && manager) {
|
|
1106
|
+
operations.push(this.runBestEffortNativeOperation('release: cancel notify transaction', () => manager.cancelTransaction(transport.notifyTransactionId)));
|
|
1107
|
+
}
|
|
1108
|
+
if (manager) {
|
|
1109
|
+
operations.push(this.runBestEffortNativeOperation('release: cancel transaction', () => manager.cancelTransaction(uuid)));
|
|
1110
|
+
}
|
|
1111
|
+
yield Promise.all(operations);
|
|
1112
|
+
}));
|
|
1008
1113
|
return Promise.resolve(true);
|
|
1009
1114
|
});
|
|
1010
1115
|
}
|
|
1011
1116
|
post(session, name, data) {
|
|
1012
1117
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1118
|
+
if (this.getProtocolType(session) === 'V2') {
|
|
1119
|
+
yield this.protocolV2Links.sendFlowControl(session, () => this.createProtocolV2Adapter(session), name, data);
|
|
1120
|
+
return;
|
|
1121
|
+
}
|
|
1013
1122
|
yield this.call(session, name, data);
|
|
1014
1123
|
});
|
|
1015
1124
|
}
|
|
@@ -1025,7 +1134,6 @@ class ReactNativeBleTransport {
|
|
|
1025
1134
|
if (!protocol) {
|
|
1026
1135
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Device protocol has not been detected for ${uuid}`);
|
|
1027
1136
|
}
|
|
1028
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('transport call', createTransportCallLog(name, protocol, data));
|
|
1029
1137
|
if (protocol === 'V2') {
|
|
1030
1138
|
return this.callProtocolV2(uuid, name, data, options);
|
|
1031
1139
|
}
|
|
@@ -1044,7 +1152,19 @@ class ReactNativeBleTransport {
|
|
|
1044
1152
|
const transport = this.getCachedTransport(uuid);
|
|
1045
1153
|
const runPromise = hdShared.createDeferred();
|
|
1046
1154
|
runPromise.promise.catch(() => undefined);
|
|
1155
|
+
const supersededRunPromise = this.runPromise;
|
|
1156
|
+
if (supersededRunPromise) {
|
|
1157
|
+
supersededRunPromise.reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleForceCleanRunPromise));
|
|
1158
|
+
}
|
|
1047
1159
|
this.runPromise = runPromise;
|
|
1160
|
+
this.runPromiseDeviceId = uuid;
|
|
1161
|
+
const releaseOwnershipIfCurrent = () => {
|
|
1162
|
+
if (this.runPromise === runPromise) {
|
|
1163
|
+
this.runPromise = null;
|
|
1164
|
+
this.runPromiseDeviceId = null;
|
|
1165
|
+
}
|
|
1166
|
+
};
|
|
1167
|
+
const isCurrentOwner = () => this.runPromise === runPromise;
|
|
1048
1168
|
const messages = this._messages;
|
|
1049
1169
|
const buffers = ProtocolV1.encodeTransportPackets(messages, name, data);
|
|
1050
1170
|
let timeout;
|
|
@@ -1065,6 +1185,9 @@ class ReactNativeBleTransport {
|
|
|
1065
1185
|
}
|
|
1066
1186
|
catch (e) {
|
|
1067
1187
|
onError(e);
|
|
1188
|
+
if (isWedgedWriteError(e)) {
|
|
1189
|
+
throw e;
|
|
1190
|
+
}
|
|
1068
1191
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleWriteCharacteristicError);
|
|
1069
1192
|
}
|
|
1070
1193
|
}
|
|
@@ -1092,6 +1215,9 @@ class ReactNativeBleTransport {
|
|
|
1092
1215
|
}
|
|
1093
1216
|
catch (e) {
|
|
1094
1217
|
onError(e);
|
|
1218
|
+
if (isWedgedWriteError(e)) {
|
|
1219
|
+
throw e;
|
|
1220
|
+
}
|
|
1095
1221
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleWriteCharacteristicError);
|
|
1096
1222
|
}
|
|
1097
1223
|
}
|
|
@@ -1102,8 +1228,8 @@ class ReactNativeBleTransport {
|
|
|
1102
1228
|
});
|
|
1103
1229
|
}
|
|
1104
1230
|
if (name === 'EmmcFileWrite') {
|
|
1105
|
-
yield writeChunkedData(buffers, data => transport.writeWithRetry(
|
|
1106
|
-
|
|
1231
|
+
yield writeChunkedData(buffers, data => this.writeBlePacket(uuid, data, payload => transport.writeWithRetry(payload), isCurrentOwner), e => {
|
|
1232
|
+
releaseOwnershipIfCurrent();
|
|
1107
1233
|
Log === null || Log === void 0 ? void 0 : Log.error('writeCharacteristic write error: ', e);
|
|
1108
1234
|
});
|
|
1109
1235
|
}
|
|
@@ -1119,7 +1245,7 @@ class ReactNativeBleTransport {
|
|
|
1119
1245
|
let attempt = 0;
|
|
1120
1246
|
while (true) {
|
|
1121
1247
|
try {
|
|
1122
|
-
yield transport.
|
|
1248
|
+
yield this.writeBlePacket(uuid, data, payload => transport.writeWithRetry(payload), isCurrentOwner);
|
|
1123
1249
|
return;
|
|
1124
1250
|
}
|
|
1125
1251
|
catch (error) {
|
|
@@ -1127,36 +1253,18 @@ class ReactNativeBleTransport {
|
|
|
1127
1253
|
if (!retryType || attempt >= FIRMWARE_UPLOAD_WRITE_MAX_RETRIES) {
|
|
1128
1254
|
throw error;
|
|
1129
1255
|
}
|
|
1130
|
-
const
|
|
1131
|
-
const delayMs = shouldReconnect
|
|
1132
|
-
? FIRMWARE_UPLOAD_RECONNECT_RETRY_DELAY_MS
|
|
1133
|
-
: resolveFirmwareUploadRetryDelay(attempt);
|
|
1256
|
+
const delayMs = resolveFirmwareUploadRetryDelay(attempt);
|
|
1134
1257
|
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] FirmwareUpload write retry:', {
|
|
1135
1258
|
attempt: attempt + 1,
|
|
1136
1259
|
delayMs,
|
|
1137
|
-
reconnect: shouldReconnect,
|
|
1138
1260
|
error,
|
|
1139
1261
|
});
|
|
1140
|
-
if (shouldReconnect) {
|
|
1141
|
-
this.firmwareUploadWriteRecoveryIds.add(uuid);
|
|
1142
|
-
}
|
|
1143
1262
|
yield delay(delayMs);
|
|
1144
1263
|
attempt += 1;
|
|
1145
|
-
if (shouldReconnect) {
|
|
1146
|
-
try {
|
|
1147
|
-
yield this.reconnectFirmwareUploadTransport(uuid, transport);
|
|
1148
|
-
}
|
|
1149
|
-
catch (e) {
|
|
1150
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] FirmwareUpload reconnect error:', e);
|
|
1151
|
-
if (attempt >= FIRMWARE_UPLOAD_WRITE_MAX_RETRIES) {
|
|
1152
|
-
throw e;
|
|
1153
|
-
}
|
|
1154
|
-
}
|
|
1155
|
-
}
|
|
1156
1264
|
}
|
|
1157
1265
|
}
|
|
1158
1266
|
}), e => {
|
|
1159
|
-
|
|
1267
|
+
releaseOwnershipIfCurrent();
|
|
1160
1268
|
Log === null || Log === void 0 ? void 0 : Log.error('writeCharacteristic write error: ', e);
|
|
1161
1269
|
});
|
|
1162
1270
|
}
|
|
@@ -1164,11 +1272,17 @@ class ReactNativeBleTransport {
|
|
|
1164
1272
|
for (const o of buffers) {
|
|
1165
1273
|
const outData = o.toString('base64');
|
|
1166
1274
|
try {
|
|
1167
|
-
|
|
1275
|
+
const shouldUseWriteWithResponse = reactNative.Platform.OS === 'ios' && transport.writeCharacteristic.isWritableWithResponse;
|
|
1276
|
+
yield this.writeBlePacket(uuid, outData, payload => shouldUseWriteWithResponse
|
|
1277
|
+
? transport.writeCharacteristic.writeWithResponse(payload)
|
|
1278
|
+
: transport.writeCharacteristic.writeWithoutResponse(payload), isCurrentOwner);
|
|
1168
1279
|
}
|
|
1169
1280
|
catch (e) {
|
|
1170
1281
|
Log === null || Log === void 0 ? void 0 : Log.debug('writeCharacteristic write error: ', e);
|
|
1171
|
-
|
|
1282
|
+
releaseOwnershipIfCurrent();
|
|
1283
|
+
if (isWedgedWriteError(e)) {
|
|
1284
|
+
throw e;
|
|
1285
|
+
}
|
|
1172
1286
|
if (e.errorCode === reactNativeBlePlx.BleErrorCode.DeviceDisconnected) {
|
|
1173
1287
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceNotBonded);
|
|
1174
1288
|
}
|
|
@@ -1201,12 +1315,19 @@ class ReactNativeBleTransport {
|
|
|
1201
1315
|
return check.call(jsonData);
|
|
1202
1316
|
}
|
|
1203
1317
|
catch (e) {
|
|
1204
|
-
if (name === '
|
|
1205
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V1
|
|
1318
|
+
if (name === 'GetFeatures' && (options === null || options === void 0 ? void 0 : options.timeoutMs) === PROTOCOL_PROBE_TIMEOUT_MS) {
|
|
1319
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V1 GetFeatures probe call failed:', e);
|
|
1206
1320
|
}
|
|
1207
1321
|
else {
|
|
1208
1322
|
Log === null || Log === void 0 ? void 0 : Log.error('call error: ', e);
|
|
1209
1323
|
}
|
|
1324
|
+
const isProbeTimeout = name === 'GetFeatures' && (options === null || options === void 0 ? void 0 : options.timeoutMs) === PROTOCOL_PROBE_TIMEOUT_MS;
|
|
1325
|
+
const isStaleCall = this.runPromise !== runPromise;
|
|
1326
|
+
if (!isProbeTimeout &&
|
|
1327
|
+
!isStaleCall &&
|
|
1328
|
+
(e === null || e === void 0 ? void 0 : e.errorCode) === hdShared.HardwareErrorCode.BleTimeoutError) {
|
|
1329
|
+
yield this.disconnect(uuid);
|
|
1330
|
+
}
|
|
1210
1331
|
throw e;
|
|
1211
1332
|
}
|
|
1212
1333
|
finally {
|
|
@@ -1214,6 +1335,7 @@ class ReactNativeBleTransport {
|
|
|
1214
1335
|
clearTimeout(timeout);
|
|
1215
1336
|
if (this.runPromise === runPromise) {
|
|
1216
1337
|
this.runPromise = null;
|
|
1338
|
+
this.runPromiseDeviceId = null;
|
|
1217
1339
|
}
|
|
1218
1340
|
}
|
|
1219
1341
|
});
|
|
@@ -1222,10 +1344,17 @@ class ReactNativeBleTransport {
|
|
|
1222
1344
|
this.stopped = true;
|
|
1223
1345
|
}
|
|
1224
1346
|
disconnect(session) {
|
|
1225
|
-
|
|
1347
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1348
|
+
return this.runLifecycleOperation(session, () => this.disconnectUnlocked(session));
|
|
1349
|
+
});
|
|
1350
|
+
}
|
|
1351
|
+
disconnectUnlocked(session) {
|
|
1352
|
+
var _a, _b, _c;
|
|
1226
1353
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1227
1354
|
yield this.protocolV2Links.invalidateLink(session, 'React Native BLE transport disconnected');
|
|
1228
1355
|
const transport = transportCache[session];
|
|
1356
|
+
const manager = this.blePlxManager;
|
|
1357
|
+
const monitorToken = (_a = transport === null || transport === void 0 ? void 0 : transport.monitorToken) !== null && _a !== void 0 ? _a : this.monitorTokens.get(session);
|
|
1229
1358
|
if (transport === null || transport === void 0 ? void 0 : transport.disconnectSubscription) {
|
|
1230
1359
|
try {
|
|
1231
1360
|
Log === null || Log === void 0 ? void 0 : Log.debug('disconnect: removing disconnect subscription');
|
|
@@ -1238,7 +1367,7 @@ class ReactNativeBleTransport {
|
|
|
1238
1367
|
}
|
|
1239
1368
|
if (transport === null || transport === void 0 ? void 0 : transport.notifySubscription) {
|
|
1240
1369
|
try {
|
|
1241
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('disconnect: removing notify subscription, characteristic: ', (
|
|
1370
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('disconnect: removing notify subscription, characteristic: ', (_b = transport.notifyCharacteristic) === null || _b === void 0 ? void 0 : _b.uuid);
|
|
1242
1371
|
transport.notifySubscription.remove();
|
|
1243
1372
|
transport.notifySubscription = undefined;
|
|
1244
1373
|
}
|
|
@@ -1246,52 +1375,190 @@ class ReactNativeBleTransport {
|
|
|
1246
1375
|
Log === null || Log === void 0 ? void 0 : Log.error('disconnect: remove notify subscription error: ', e);
|
|
1247
1376
|
}
|
|
1248
1377
|
}
|
|
1249
|
-
if (session) {
|
|
1250
|
-
try {
|
|
1251
|
-
yield ((_b = this.blePlxManager) === null || _b === void 0 ? void 0 : _b.cancelTransaction(session));
|
|
1252
|
-
}
|
|
1253
|
-
catch (e) {
|
|
1254
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('resetSession: cancel transaction error (ignored): ', (e === null || e === void 0 ? void 0 : e.message) || e);
|
|
1255
|
-
}
|
|
1256
|
-
}
|
|
1257
|
-
if (transport === null || transport === void 0 ? void 0 : transport.device) {
|
|
1258
|
-
try {
|
|
1259
|
-
yield transport.device.cancelConnection();
|
|
1260
|
-
}
|
|
1261
|
-
catch (e) {
|
|
1262
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('resetSession: device.cancelConnection error (ignored): ', (e === null || e === void 0 ? void 0 : e.message) || e);
|
|
1263
|
-
}
|
|
1264
|
-
}
|
|
1265
|
-
try {
|
|
1266
|
-
yield ((_c = this.blePlxManager) === null || _c === void 0 ? void 0 : _c.cancelDeviceConnection(session));
|
|
1267
|
-
}
|
|
1268
|
-
catch (e) {
|
|
1269
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('resetSession: manager.cancelDeviceConnection error (ignored): ', (e === null || e === void 0 ? void 0 : e.message) || e);
|
|
1270
|
-
}
|
|
1271
|
-
if (transportCache[session]) {
|
|
1378
|
+
if (!transport || transportCache[session] === transport) {
|
|
1272
1379
|
delete transportCache[session];
|
|
1273
1380
|
}
|
|
1274
1381
|
this.deviceProtocol.delete(session);
|
|
1382
|
+
this.probingProtocols.delete(session);
|
|
1275
1383
|
this.deviceProtocolHints.delete(session);
|
|
1384
|
+
this.sessionProtocols.delete(session);
|
|
1385
|
+
this.protocolReprobeFailures.delete(session);
|
|
1276
1386
|
this.protocolV2Assemblers.delete(session);
|
|
1277
1387
|
this.resetProtocolV2Frames(session);
|
|
1278
1388
|
try {
|
|
1279
|
-
(
|
|
1280
|
-
name: (_e = transport === null || transport === void 0 ? void 0 : transport.device) === null || _e === void 0 ? void 0 : _e.name,
|
|
1281
|
-
id: session,
|
|
1282
|
-
connectId: session,
|
|
1283
|
-
});
|
|
1389
|
+
this.emitDeviceDisconnect(session, (_c = transport === null || transport === void 0 ? void 0 : transport.device) === null || _c === void 0 ? void 0 : _c.name, monitorToken);
|
|
1284
1390
|
}
|
|
1285
1391
|
catch (e) {
|
|
1286
1392
|
Log === null || Log === void 0 ? void 0 : Log.error('resetSession: emit disconnect event error: ', e);
|
|
1287
1393
|
}
|
|
1394
|
+
if (monitorToken !== undefined && this.monitorTokens.get(session) === monitorToken) {
|
|
1395
|
+
this.monitorTokens.delete(session);
|
|
1396
|
+
}
|
|
1397
|
+
yield this.runNativeTeardown(session, manager, () => __awaiter(this, void 0, void 0, function* () {
|
|
1398
|
+
const operations = [];
|
|
1399
|
+
if (manager) {
|
|
1400
|
+
operations.push(this.runBestEffortNativeOperation('disconnect: cancel transaction', () => manager.cancelTransaction(session)));
|
|
1401
|
+
operations.push(this.runBestEffortNativeOperation('disconnect: cancel device connection', () => manager.cancelDeviceConnection(session)));
|
|
1402
|
+
}
|
|
1403
|
+
if (transport === null || transport === void 0 ? void 0 : transport.device) {
|
|
1404
|
+
operations.push(this.runBestEffortNativeOperation('disconnect: device cancel connection', () => transport.device.cancelConnection()));
|
|
1405
|
+
}
|
|
1406
|
+
yield Promise.all(operations);
|
|
1407
|
+
}));
|
|
1288
1408
|
yield new Promise(resolve => setTimeout(() => resolve(), 100));
|
|
1289
1409
|
});
|
|
1290
1410
|
}
|
|
1411
|
+
runNativeTeardown(uuid, manager, teardown) {
|
|
1412
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1413
|
+
let timer;
|
|
1414
|
+
let timedOut = false;
|
|
1415
|
+
const pending = Promise.resolve()
|
|
1416
|
+
.then(teardown)
|
|
1417
|
+
.catch(error => {
|
|
1418
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('BLE native teardown error (ignored): ', (error === null || error === void 0 ? void 0 : error.message) || error);
|
|
1419
|
+
});
|
|
1420
|
+
try {
|
|
1421
|
+
yield Promise.race([
|
|
1422
|
+
pending,
|
|
1423
|
+
new Promise(resolve => {
|
|
1424
|
+
timer = setTimeout(() => {
|
|
1425
|
+
timedOut = true;
|
|
1426
|
+
resolve();
|
|
1427
|
+
}, BLE_NATIVE_TEARDOWN_TIMEOUT_MS);
|
|
1428
|
+
}),
|
|
1429
|
+
]);
|
|
1430
|
+
}
|
|
1431
|
+
finally {
|
|
1432
|
+
if (timer)
|
|
1433
|
+
clearTimeout(timer);
|
|
1434
|
+
}
|
|
1435
|
+
if (timedOut) {
|
|
1436
|
+
Log === null || Log === void 0 ? void 0 : Log.error('[ReactNativeBleTransport] BLE native teardown timed out:', uuid);
|
|
1437
|
+
if (this.blePlxManager === manager) {
|
|
1438
|
+
this.resetPlxManager();
|
|
1439
|
+
}
|
|
1440
|
+
}
|
|
1441
|
+
});
|
|
1442
|
+
}
|
|
1443
|
+
runBestEffortNativeOperation(label, operation) {
|
|
1444
|
+
return Promise.resolve()
|
|
1445
|
+
.then(operation)
|
|
1446
|
+
.catch(error => {
|
|
1447
|
+
Log === null || Log === void 0 ? void 0 : Log.debug(`${label} error (ignored): `, (error === null || error === void 0 ? void 0 : error.message) || error);
|
|
1448
|
+
});
|
|
1449
|
+
}
|
|
1450
|
+
runLifecycleOperation(uuid, operation) {
|
|
1451
|
+
var _a;
|
|
1452
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1453
|
+
const previousOperation = (_a = this.lifecycleOperations.get(uuid)) !== null && _a !== void 0 ? _a : Promise.resolve();
|
|
1454
|
+
let completeOperation;
|
|
1455
|
+
const operationGate = new Promise(resolve => {
|
|
1456
|
+
completeOperation = resolve;
|
|
1457
|
+
});
|
|
1458
|
+
const operationTail = previousOperation.catch(() => undefined).then(() => operationGate);
|
|
1459
|
+
this.lifecycleOperations.set(uuid, operationTail);
|
|
1460
|
+
yield previousOperation.catch(() => undefined);
|
|
1461
|
+
try {
|
|
1462
|
+
return yield operation();
|
|
1463
|
+
}
|
|
1464
|
+
finally {
|
|
1465
|
+
completeOperation();
|
|
1466
|
+
if (this.lifecycleOperations.get(uuid) === operationTail) {
|
|
1467
|
+
this.lifecycleOperations.delete(uuid);
|
|
1468
|
+
}
|
|
1469
|
+
}
|
|
1470
|
+
});
|
|
1471
|
+
}
|
|
1291
1472
|
cancel() {
|
|
1292
1473
|
Log === null || Log === void 0 ? void 0 : Log.debug('transport-react-native transport cancel');
|
|
1293
1474
|
if (this.runPromise) ;
|
|
1294
1475
|
this.runPromise = null;
|
|
1476
|
+
this.runPromiseDeviceId = null;
|
|
1477
|
+
}
|
|
1478
|
+
connectWithTimeout(uuid, connect) {
|
|
1479
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1480
|
+
let timer;
|
|
1481
|
+
let timedOut = false;
|
|
1482
|
+
const pending = connect();
|
|
1483
|
+
pending.catch(() => undefined);
|
|
1484
|
+
try {
|
|
1485
|
+
const result = yield Promise.race([
|
|
1486
|
+
pending,
|
|
1487
|
+
new Promise((_, reject) => {
|
|
1488
|
+
timer = setTimeout(() => {
|
|
1489
|
+
timedOut = true;
|
|
1490
|
+
reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleConnectedError, `BLE connect timeout after ${BLE_CONNECT_TIMEOUT_MS}ms for ${uuid}`));
|
|
1491
|
+
}, BLE_CONNECT_TIMEOUT_MS);
|
|
1492
|
+
}),
|
|
1493
|
+
]);
|
|
1494
|
+
return result;
|
|
1495
|
+
}
|
|
1496
|
+
catch (error) {
|
|
1497
|
+
if (timedOut || isNativeOperationTimeoutError(error)) {
|
|
1498
|
+
this.abandonStalledConnection(uuid, timedOut ? 'connect-backstop' : 'connect-native');
|
|
1499
|
+
}
|
|
1500
|
+
throw error;
|
|
1501
|
+
}
|
|
1502
|
+
finally {
|
|
1503
|
+
if (timer)
|
|
1504
|
+
clearTimeout(timer);
|
|
1505
|
+
}
|
|
1506
|
+
});
|
|
1507
|
+
}
|
|
1508
|
+
resolveCharacteristicsWithTimeout(uuid, device) {
|
|
1509
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1510
|
+
let timer;
|
|
1511
|
+
let timedOut = false;
|
|
1512
|
+
const pending = this.resolveCharacteristics(device);
|
|
1513
|
+
pending.catch(() => undefined);
|
|
1514
|
+
try {
|
|
1515
|
+
const result = yield Promise.race([
|
|
1516
|
+
pending,
|
|
1517
|
+
new Promise((_, reject) => {
|
|
1518
|
+
timer = setTimeout(() => {
|
|
1519
|
+
timedOut = true;
|
|
1520
|
+
reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleConnectedError, `BLE GATT setup timeout after ${BLE_GATT_SETUP_TIMEOUT_MS}ms for ${uuid}`));
|
|
1521
|
+
}, BLE_GATT_SETUP_TIMEOUT_MS);
|
|
1522
|
+
}),
|
|
1523
|
+
]);
|
|
1524
|
+
this.connectionSetupTimeoutCounts.delete(uuid);
|
|
1525
|
+
return result;
|
|
1526
|
+
}
|
|
1527
|
+
catch (error) {
|
|
1528
|
+
if (timedOut || isNativeOperationTimeoutError(error)) {
|
|
1529
|
+
this.abandonStalledConnection(uuid, timedOut ? 'gatt-backstop' : 'gatt-native');
|
|
1530
|
+
}
|
|
1531
|
+
throw error;
|
|
1532
|
+
}
|
|
1533
|
+
finally {
|
|
1534
|
+
if (timer)
|
|
1535
|
+
clearTimeout(timer);
|
|
1536
|
+
}
|
|
1537
|
+
});
|
|
1538
|
+
}
|
|
1539
|
+
abandonStalledConnection(uuid, stage) {
|
|
1540
|
+
var _a, _b;
|
|
1541
|
+
const timeouts = ((_a = this.connectionSetupTimeoutCounts.get(uuid)) !== null && _a !== void 0 ? _a : 0) + 1;
|
|
1542
|
+
this.connectionSetupTimeoutCounts.set(uuid, timeouts);
|
|
1543
|
+
Log === null || Log === void 0 ? void 0 : Log.error('[ReactNativeBleTransport] BLE setup timed out:', uuid, {
|
|
1544
|
+
stage,
|
|
1545
|
+
setupTimeoutsSinceSuccess: timeouts,
|
|
1546
|
+
});
|
|
1547
|
+
(_b = this.blePlxManager) === null || _b === void 0 ? void 0 : _b.cancelDeviceConnection(uuid).catch(() => {
|
|
1548
|
+
});
|
|
1549
|
+
const stalled = transportCache[uuid];
|
|
1550
|
+
if (stalled) {
|
|
1551
|
+
delete transportCache[uuid];
|
|
1552
|
+
}
|
|
1553
|
+
this.deviceProtocol.delete(uuid);
|
|
1554
|
+
this.probingProtocols.delete(uuid);
|
|
1555
|
+
this.protocolV2Assemblers.delete(uuid);
|
|
1556
|
+
this.resetProtocolV2Frames(uuid);
|
|
1557
|
+
if (timeouts >= BLE_CONNECT_TIMEOUT_MANAGER_RESET_THRESHOLD) {
|
|
1558
|
+
Log === null || Log === void 0 ? void 0 : Log.error('[ReactNativeBleTransport] BLE setup wedged repeatedly, resetting BLE manager');
|
|
1559
|
+
this.resetPlxManager();
|
|
1560
|
+
this.connectionSetupTimeoutCounts.delete(uuid);
|
|
1561
|
+
}
|
|
1295
1562
|
}
|
|
1296
1563
|
getCachedTransport(uuid) {
|
|
1297
1564
|
const transport = transportCache[uuid];
|
|
@@ -1300,22 +1567,144 @@ class ReactNativeBleTransport {
|
|
|
1300
1567
|
}
|
|
1301
1568
|
return transport;
|
|
1302
1569
|
}
|
|
1570
|
+
writeBlePacket(uuid, data, write, isCurrentOwner) {
|
|
1571
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1572
|
+
let timer;
|
|
1573
|
+
let timedOut = false;
|
|
1574
|
+
try {
|
|
1575
|
+
yield Promise.race([
|
|
1576
|
+
write(data),
|
|
1577
|
+
new Promise((_, reject) => {
|
|
1578
|
+
timer = setTimeout(() => {
|
|
1579
|
+
timedOut = true;
|
|
1580
|
+
reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleWriteCharacteristicError, `BLE write timeout after ${BLE_WRITE_PACKET_TIMEOUT_MS}ms`));
|
|
1581
|
+
}, BLE_WRITE_PACKET_TIMEOUT_MS);
|
|
1582
|
+
}),
|
|
1583
|
+
]);
|
|
1584
|
+
this.writeTimeoutCounts.delete(uuid);
|
|
1585
|
+
}
|
|
1586
|
+
catch (error) {
|
|
1587
|
+
if (timedOut) {
|
|
1588
|
+
if (isCurrentOwner && !isCurrentOwner()) {
|
|
1589
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] stale BLE write timed out, link kept:', uuid);
|
|
1590
|
+
}
|
|
1591
|
+
else {
|
|
1592
|
+
this.tearDownWedgedLink(uuid);
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
1595
|
+
throw error;
|
|
1596
|
+
}
|
|
1597
|
+
finally {
|
|
1598
|
+
if (timer)
|
|
1599
|
+
clearTimeout(timer);
|
|
1600
|
+
}
|
|
1601
|
+
});
|
|
1602
|
+
}
|
|
1603
|
+
tearDownWedgedLink(uuid) {
|
|
1604
|
+
var _a;
|
|
1605
|
+
const timeouts = ((_a = this.writeTimeoutCounts.get(uuid)) !== null && _a !== void 0 ? _a : 0) + 1;
|
|
1606
|
+
this.writeTimeoutCounts.set(uuid, timeouts);
|
|
1607
|
+
Log === null || Log === void 0 ? void 0 : Log.error('[ReactNativeBleTransport] BLE write timed out, tearing down link:', uuid, {
|
|
1608
|
+
consecutiveWriteTimeouts: timeouts,
|
|
1609
|
+
});
|
|
1610
|
+
const wedged = transportCache[uuid];
|
|
1611
|
+
this.disconnect(uuid).catch(error => {
|
|
1612
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] wedged link teardown failed (ignored):', error);
|
|
1613
|
+
});
|
|
1614
|
+
if (wedged && transportCache[uuid] === wedged) {
|
|
1615
|
+
delete transportCache[uuid];
|
|
1616
|
+
}
|
|
1617
|
+
this.deviceProtocol.delete(uuid);
|
|
1618
|
+
this.probingProtocols.delete(uuid);
|
|
1619
|
+
this.protocolV2Assemblers.delete(uuid);
|
|
1620
|
+
this.resetProtocolV2Frames(uuid);
|
|
1621
|
+
if (timeouts >= BLE_WRITE_TIMEOUT_MANAGER_RESET_THRESHOLD) {
|
|
1622
|
+
Log === null || Log === void 0 ? void 0 : Log.error('[ReactNativeBleTransport] BLE writes wedged repeatedly, resetting BLE manager');
|
|
1623
|
+
this.resetPlxManager();
|
|
1624
|
+
this.writeTimeoutCounts.delete(uuid);
|
|
1625
|
+
}
|
|
1626
|
+
}
|
|
1627
|
+
resetPlxManager() {
|
|
1628
|
+
const manager = this.blePlxManager;
|
|
1629
|
+
this.blePlxManager = undefined;
|
|
1630
|
+
const reason = 'React Native BLE manager reset';
|
|
1631
|
+
Object.entries(transportCache).forEach(([uuid, cachedTransport]) => {
|
|
1632
|
+
var _a, _b, _c, _d;
|
|
1633
|
+
try {
|
|
1634
|
+
(_a = cachedTransport.disconnectSubscription) === null || _a === void 0 ? void 0 : _a.remove();
|
|
1635
|
+
}
|
|
1636
|
+
catch (error) {
|
|
1637
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('BLE manager reset disconnect subscription removal failed:', error);
|
|
1638
|
+
}
|
|
1639
|
+
cachedTransport.disconnectSubscription = undefined;
|
|
1640
|
+
try {
|
|
1641
|
+
(_b = cachedTransport.notifySubscription) === null || _b === void 0 ? void 0 : _b.remove();
|
|
1642
|
+
}
|
|
1643
|
+
catch (error) {
|
|
1644
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('BLE manager reset notify subscription removal failed:', error);
|
|
1645
|
+
}
|
|
1646
|
+
cachedTransport.notifySubscription = undefined;
|
|
1647
|
+
this.rejectProtocolV2Frames(uuid, new Error(reason));
|
|
1648
|
+
try {
|
|
1649
|
+
this.emitDeviceDisconnect(uuid, (_c = cachedTransport.device) === null || _c === void 0 ? void 0 : _c.name, (_d = cachedTransport.monitorToken) !== null && _d !== void 0 ? _d : this.monitorTokens.get(uuid));
|
|
1650
|
+
}
|
|
1651
|
+
catch (error) {
|
|
1652
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('BLE manager reset disconnect event failed:', error);
|
|
1653
|
+
}
|
|
1654
|
+
delete transportCache[uuid];
|
|
1655
|
+
});
|
|
1656
|
+
this.protocolV2Links.invalidateAllLinks(reason).catch(error => {
|
|
1657
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] BLE manager link invalidation failed:', error);
|
|
1658
|
+
});
|
|
1659
|
+
this.deviceProtocol.clear();
|
|
1660
|
+
this.probingProtocols.clear();
|
|
1661
|
+
this.sessionProtocols.clear();
|
|
1662
|
+
this.protocolReprobeFailures.clear();
|
|
1663
|
+
this.writeTimeoutCounts.clear();
|
|
1664
|
+
this.connectionSetupTimeoutCounts.clear();
|
|
1665
|
+
this.monitorTokens.clear();
|
|
1666
|
+
this.protocolV2Assemblers.clear();
|
|
1667
|
+
try {
|
|
1668
|
+
manager === null || manager === void 0 ? void 0 : manager.destroy();
|
|
1669
|
+
}
|
|
1670
|
+
catch (error) {
|
|
1671
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] BLE manager destroy failed (ignored):', error);
|
|
1672
|
+
}
|
|
1673
|
+
}
|
|
1303
1674
|
createProtocolMismatchError(expected) {
|
|
1304
1675
|
return hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Device protocol mismatch: expected ${expected}, but device did not respond to expected protocol`);
|
|
1305
1676
|
}
|
|
1306
1677
|
createProtocolDetectionError() {
|
|
1307
|
-
return hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleTimeoutError, 'Unable to detect BLE protocol: device did not respond to Protocol V1
|
|
1678
|
+
return hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleTimeoutError, 'Unable to detect BLE protocol: device did not respond to Protocol V1 GetFeatures or Protocol V2 Ping');
|
|
1308
1679
|
}
|
|
1309
1680
|
clearProbeProtocol(uuid, protocol) {
|
|
1681
|
+
if (this.probingProtocols.get(uuid) === protocol) {
|
|
1682
|
+
this.probingProtocols.delete(uuid);
|
|
1683
|
+
}
|
|
1310
1684
|
if (this.deviceProtocol.get(uuid) === protocol) {
|
|
1311
1685
|
this.deviceProtocol.delete(uuid);
|
|
1312
1686
|
}
|
|
1313
1687
|
}
|
|
1314
|
-
|
|
1688
|
+
getActiveProtocol(uuid) {
|
|
1689
|
+
var _a;
|
|
1690
|
+
return (_a = this.deviceProtocol.get(uuid)) !== null && _a !== void 0 ? _a : this.probingProtocols.get(uuid);
|
|
1691
|
+
}
|
|
1692
|
+
detectProtocol(uuid, expectedProtocol, protocolHint, rebuildTransport) {
|
|
1693
|
+
var _a;
|
|
1315
1694
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1695
|
+
if (reactNative.Platform.OS === 'ios' && expectedProtocol === 'V1') {
|
|
1696
|
+
this.deviceProtocol.set(uuid, expectedProtocol);
|
|
1697
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] protocol selected', {
|
|
1698
|
+
deviceId: uuid,
|
|
1699
|
+
protocol: expectedProtocol,
|
|
1700
|
+
source: 'expected',
|
|
1701
|
+
});
|
|
1702
|
+
return expectedProtocol;
|
|
1703
|
+
}
|
|
1316
1704
|
if (expectedProtocol === 'V1') {
|
|
1317
1705
|
if (yield this.probeProtocolV1(uuid)) {
|
|
1318
1706
|
this.deviceProtocol.set(uuid, 'V1');
|
|
1707
|
+
this.sessionProtocols.set(uuid, 'V1');
|
|
1319
1708
|
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] protocol detected', {
|
|
1320
1709
|
deviceId: uuid,
|
|
1321
1710
|
protocol: 'V1',
|
|
@@ -1326,23 +1715,41 @@ class ReactNativeBleTransport {
|
|
|
1326
1715
|
throw this.createProtocolMismatchError(expectedProtocol);
|
|
1327
1716
|
}
|
|
1328
1717
|
if (expectedProtocol === 'V2') {
|
|
1329
|
-
this.
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1718
|
+
if (yield this.probeProtocolV2(uuid)) {
|
|
1719
|
+
this.deviceProtocol.set(uuid, 'V2');
|
|
1720
|
+
this.sessionProtocols.set(uuid, 'V2');
|
|
1721
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] protocol detected', {
|
|
1722
|
+
deviceId: uuid,
|
|
1723
|
+
protocol: 'V2',
|
|
1724
|
+
source: 'expected',
|
|
1725
|
+
});
|
|
1726
|
+
return 'V2';
|
|
1727
|
+
}
|
|
1728
|
+
throw this.createProtocolMismatchError(expectedProtocol);
|
|
1336
1729
|
}
|
|
1337
|
-
const
|
|
1730
|
+
const sessionProtocol = this.sessionProtocols.get(uuid);
|
|
1731
|
+
const reprobeFailures = (_a = this.protocolReprobeFailures.get(uuid)) !== null && _a !== void 0 ? _a : 0;
|
|
1732
|
+
const fullProbeOrder = protocolHint === 'V2' || this.deviceProtocol.get(uuid) === 'V2' ? ['V2', 'V1'] : ['V1', 'V2'];
|
|
1733
|
+
const trustSessionProtocol = sessionProtocol !== undefined &&
|
|
1734
|
+
!protocolHint &&
|
|
1735
|
+
reprobeFailures < PROTOCOL_REPROBE_FALLBACK_ATTEMPTS;
|
|
1736
|
+
const probeOrder = trustSessionProtocol ? [sessionProtocol] : fullProbeOrder;
|
|
1338
1737
|
for (let i = 0; i < probeOrder.length; i += 1) {
|
|
1339
1738
|
const protocol = probeOrder[i];
|
|
1340
1739
|
if (i > 0) {
|
|
1341
1740
|
yield this.resetProbeStateAfterProtocolProbe(uuid, probeOrder[i - 1]);
|
|
1741
|
+
if (!transportCache[uuid]) {
|
|
1742
|
+
if (!rebuildTransport) {
|
|
1743
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.TransportNotFound);
|
|
1744
|
+
}
|
|
1745
|
+
yield rebuildTransport();
|
|
1746
|
+
}
|
|
1342
1747
|
}
|
|
1343
1748
|
const detected = protocol === 'V1' ? yield this.probeProtocolV1(uuid) : yield this.probeProtocolV2(uuid);
|
|
1344
1749
|
if (detected) {
|
|
1345
1750
|
this.deviceProtocol.set(uuid, protocol);
|
|
1751
|
+
this.sessionProtocols.set(uuid, protocol);
|
|
1752
|
+
this.protocolReprobeFailures.delete(uuid);
|
|
1346
1753
|
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] protocol detected', {
|
|
1347
1754
|
deviceId: uuid,
|
|
1348
1755
|
protocol,
|
|
@@ -1351,7 +1758,14 @@ class ReactNativeBleTransport {
|
|
|
1351
1758
|
return protocol;
|
|
1352
1759
|
}
|
|
1353
1760
|
}
|
|
1761
|
+
if (trustSessionProtocol) {
|
|
1762
|
+
this.protocolReprobeFailures.set(uuid, reprobeFailures + 1);
|
|
1763
|
+
}
|
|
1764
|
+
else {
|
|
1765
|
+
this.protocolReprobeFailures.delete(uuid);
|
|
1766
|
+
}
|
|
1354
1767
|
this.deviceProtocol.delete(uuid);
|
|
1768
|
+
this.probingProtocols.delete(uuid);
|
|
1355
1769
|
throw this.createProtocolDetectionError();
|
|
1356
1770
|
});
|
|
1357
1771
|
}
|
|
@@ -1403,13 +1817,17 @@ class ReactNativeBleTransport {
|
|
|
1403
1817
|
return false;
|
|
1404
1818
|
}
|
|
1405
1819
|
try {
|
|
1406
|
-
this.
|
|
1407
|
-
yield this.callProtocolV1(uuid, '
|
|
1820
|
+
this.probingProtocols.set(uuid, 'V1');
|
|
1821
|
+
yield this.callProtocolV1(uuid, 'GetFeatures', {}, { timeoutMs: PROTOCOL_PROBE_TIMEOUT_MS });
|
|
1822
|
+
this.probingProtocols.delete(uuid);
|
|
1408
1823
|
return true;
|
|
1409
1824
|
}
|
|
1410
1825
|
catch (error) {
|
|
1411
1826
|
this.clearProbeProtocol(uuid, 'V1');
|
|
1412
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V1
|
|
1827
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V1 GetFeatures probe failed:', error);
|
|
1828
|
+
if (isWedgedWriteError(error)) {
|
|
1829
|
+
throw error;
|
|
1830
|
+
}
|
|
1413
1831
|
return false;
|
|
1414
1832
|
}
|
|
1415
1833
|
});
|
|
@@ -1420,7 +1838,7 @@ class ReactNativeBleTransport {
|
|
|
1420
1838
|
if (!this._messages || !this._messagesV2) {
|
|
1421
1839
|
return false;
|
|
1422
1840
|
}
|
|
1423
|
-
this.
|
|
1841
|
+
this.probingProtocols.set(uuid, 'V2');
|
|
1424
1842
|
(_a = this.protocolV2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
|
|
1425
1843
|
const detected = yield transport.probeProtocolV2({
|
|
1426
1844
|
call: (name, data, options) => this.callProtocolV2(uuid, name, data, options),
|
|
@@ -1436,6 +1854,9 @@ class ReactNativeBleTransport {
|
|
|
1436
1854
|
if (!detected) {
|
|
1437
1855
|
this.clearProbeProtocol(uuid, 'V2');
|
|
1438
1856
|
}
|
|
1857
|
+
else {
|
|
1858
|
+
this.probingProtocols.delete(uuid);
|
|
1859
|
+
}
|
|
1439
1860
|
return detected;
|
|
1440
1861
|
});
|
|
1441
1862
|
}
|
|
@@ -1478,16 +1899,8 @@ class ReactNativeBleTransport {
|
|
|
1478
1899
|
}
|
|
1479
1900
|
this.getProtocolV2FrameQueue(uuid).push(frame);
|
|
1480
1901
|
}
|
|
1481
|
-
rejectAllProtocolV2Frames(error) {
|
|
1482
|
-
this.protocolV2FrameQueues.clear();
|
|
1483
|
-
for (const framePromise of this.protocolV2FramePromises.values()) {
|
|
1484
|
-
framePromise.reject(error);
|
|
1485
|
-
}
|
|
1486
|
-
this.protocolV2FramePromises.clear();
|
|
1487
|
-
}
|
|
1488
1902
|
resetProtocolV2Frames(uuid) {
|
|
1489
|
-
this.
|
|
1490
|
-
this.protocolV2FramePromises.delete(uuid);
|
|
1903
|
+
this.rejectProtocolV2Frames(uuid, new Error(`Protocol V2 frame state reset for ${uuid}`));
|
|
1491
1904
|
}
|
|
1492
1905
|
rejectProtocolV2Frames(uuid, error) {
|
|
1493
1906
|
this.protocolV2FrameQueues.delete(uuid);
|
|
@@ -1515,20 +1928,70 @@ class ReactNativeBleTransport {
|
|
|
1515
1928
|
}
|
|
1516
1929
|
});
|
|
1517
1930
|
}
|
|
1518
|
-
|
|
1931
|
+
writeProtocolV2Packet(uuid, transport, base64, context, assertCurrentGeneration) {
|
|
1932
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1933
|
+
const shouldUseWriteWithResponse = shouldWriteProtocolV2WithResponse({
|
|
1934
|
+
platform: reactNative.Platform.OS,
|
|
1935
|
+
highThroughput: context.highThroughput,
|
|
1936
|
+
requestedWithResponse: context.writeWithResponse,
|
|
1937
|
+
characteristic: transport.writeCharacteristic,
|
|
1938
|
+
});
|
|
1939
|
+
let attempt = 0;
|
|
1940
|
+
for (;;) {
|
|
1941
|
+
assertCurrentGeneration();
|
|
1942
|
+
if (context.signal.aborted) {
|
|
1943
|
+
throw new Error(`Protocol V2 BLE write aborted for ${context.messageName}`);
|
|
1944
|
+
}
|
|
1945
|
+
try {
|
|
1946
|
+
yield this.writeBlePacket(uuid, base64, payload => shouldUseWriteWithResponse
|
|
1947
|
+
? transport.writeCharacteristic.writeWithResponse(payload)
|
|
1948
|
+
: transport.writeCharacteristic.writeWithoutResponse(payload), () => {
|
|
1949
|
+
try {
|
|
1950
|
+
assertCurrentGeneration();
|
|
1951
|
+
return !context.signal.aborted;
|
|
1952
|
+
}
|
|
1953
|
+
catch (_a) {
|
|
1954
|
+
return false;
|
|
1955
|
+
}
|
|
1956
|
+
});
|
|
1957
|
+
assertCurrentGeneration();
|
|
1958
|
+
return;
|
|
1959
|
+
}
|
|
1960
|
+
catch (error) {
|
|
1961
|
+
if (getFirmwareUploadWriteRetryType(error) !== 'congested' ||
|
|
1962
|
+
attempt >= FIRMWARE_UPLOAD_WRITE_MAX_RETRIES) {
|
|
1963
|
+
throw error;
|
|
1964
|
+
}
|
|
1965
|
+
const delayMs = resolveFirmwareUploadRetryDelay(attempt);
|
|
1966
|
+
attempt += 1;
|
|
1967
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V2 congested write retry:', {
|
|
1968
|
+
name: context.messageName,
|
|
1969
|
+
attempt,
|
|
1970
|
+
delayMs,
|
|
1971
|
+
});
|
|
1972
|
+
yield delay(delayMs);
|
|
1973
|
+
}
|
|
1974
|
+
}
|
|
1975
|
+
});
|
|
1976
|
+
}
|
|
1977
|
+
writeProtocolV2Frame(uuid, transport$1, frame, context, assertCurrentGeneration) {
|
|
1519
1978
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1520
1979
|
const tuning = getProtocolV2BleTuning();
|
|
1521
1980
|
const packetCapacity = resolveProtocolV2PacketCapacity({
|
|
1522
1981
|
platform: reactNative.Platform.OS,
|
|
1523
1982
|
iosPacketLength: tuning.iosPacketLength,
|
|
1524
1983
|
androidPacketLength: tuning.androidPacketLength,
|
|
1525
|
-
mtu:
|
|
1984
|
+
mtu: transport$1.mtuSize,
|
|
1985
|
+
});
|
|
1986
|
+
yield transport.writeProtocolV2BleFrame({
|
|
1987
|
+
frame,
|
|
1988
|
+
packetCapacity,
|
|
1989
|
+
assertActive: assertCurrentGeneration,
|
|
1990
|
+
signal: context.signal,
|
|
1991
|
+
abortMessage: `Protocol V2 BLE write aborted for ${context.messageName}`,
|
|
1992
|
+
wait: delay,
|
|
1993
|
+
writePacket: packet => this.writeProtocolV2Packet(uuid, transport$1, buffer.Buffer.from(packet).toString('base64'), context, assertCurrentGeneration),
|
|
1526
1994
|
});
|
|
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);
|
|
1531
|
-
}
|
|
1532
1995
|
});
|
|
1533
1996
|
}
|
|
1534
1997
|
callProtocolV2(uuid, name, data, options) {
|
|
@@ -1537,15 +2000,40 @@ class ReactNativeBleTransport {
|
|
|
1537
2000
|
if (!this._messages || !this._messagesV2) {
|
|
1538
2001
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.TransportNotConfigured);
|
|
1539
2002
|
}
|
|
1540
|
-
const callOptions =
|
|
1541
|
-
const
|
|
1542
|
-
if (
|
|
2003
|
+
const callOptions = options;
|
|
2004
|
+
const highThroughputWrite = transport.isProtocolV2HighThroughputCall(name);
|
|
2005
|
+
if (highThroughputWrite) {
|
|
2006
|
+
yield this.ensureProtocolV2HighThroughputMtu(uuid);
|
|
1543
2007
|
const tuning = getProtocolV2BleTuning();
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
2008
|
+
const currentTransport = this.getCachedTransport(uuid);
|
|
2009
|
+
const writeWithResponse = shouldWriteProtocolV2WithResponse({
|
|
2010
|
+
platform: reactNative.Platform.OS,
|
|
2011
|
+
highThroughput: true,
|
|
2012
|
+
requestedWithResponse: options === null || options === void 0 ? void 0 : options.writeWithResponse,
|
|
2013
|
+
characteristic: currentTransport.writeCharacteristic,
|
|
2014
|
+
});
|
|
2015
|
+
const packetCapacity = resolveProtocolV2PacketCapacity({
|
|
2016
|
+
platform: reactNative.Platform.OS,
|
|
2017
|
+
iosPacketLength: tuning.iosPacketLength,
|
|
2018
|
+
androidPacketLength: tuning.androidPacketLength,
|
|
2019
|
+
mtu: currentTransport.mtuSize,
|
|
1548
2020
|
});
|
|
2021
|
+
const writeMode = writeWithResponse ? 'withResponse' : 'withoutResponse';
|
|
2022
|
+
const logSignature = `${name}:${writeMode}:${String(currentTransport.mtuSize)}:${packetCapacity}`;
|
|
2023
|
+
const loggedSignatures = (_a = this.protocolV2HighVolumeLogSignatures.get(uuid)) !== null && _a !== void 0 ? _a : new Set();
|
|
2024
|
+
if (!loggedSignatures.has(logSignature)) {
|
|
2025
|
+
loggedSignatures.add(logSignature);
|
|
2026
|
+
this.protocolV2HighVolumeLogSignatures.set(uuid, loggedSignatures);
|
|
2027
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V2 high-volume write configured', {
|
|
2028
|
+
name,
|
|
2029
|
+
writeMode,
|
|
2030
|
+
reportedMtu: currentTransport.mtuSize,
|
|
2031
|
+
packetCapacity,
|
|
2032
|
+
});
|
|
2033
|
+
}
|
|
2034
|
+
}
|
|
2035
|
+
if (highThroughputWrite) {
|
|
2036
|
+
yield this.enableAndroidHighConnectionPriority(uuid);
|
|
1549
2037
|
}
|
|
1550
2038
|
try {
|
|
1551
2039
|
return yield this.protocolV2Links.call(uuid, () => this.createProtocolV2Adapter(uuid), name, data, callOptions);
|
|
@@ -1554,6 +2042,85 @@ class ReactNativeBleTransport {
|
|
|
1554
2042
|
Log === null || Log === void 0 ? void 0 : Log.error('[ReactNativeBleTransport] Protocol V2 call error:', e);
|
|
1555
2043
|
throw e;
|
|
1556
2044
|
}
|
|
2045
|
+
finally {
|
|
2046
|
+
if (highThroughputWrite) {
|
|
2047
|
+
this.scheduleAndroidBalancedConnectionPriority(uuid);
|
|
2048
|
+
}
|
|
2049
|
+
}
|
|
2050
|
+
});
|
|
2051
|
+
}
|
|
2052
|
+
ensureProtocolV2HighThroughputMtu(uuid) {
|
|
2053
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2054
|
+
const transport = this.getCachedTransport(uuid);
|
|
2055
|
+
if (!shouldRefreshNegotiatedMtu(transport.mtuSize))
|
|
2056
|
+
return;
|
|
2057
|
+
const refreshedDevice = yield requestNegotiatedMtu(transport.device, 'highThroughput', 1);
|
|
2058
|
+
transport.device = refreshedDevice;
|
|
2059
|
+
transport.mtuSize =
|
|
2060
|
+
typeof refreshedDevice.mtu === 'number' ? refreshedDevice.mtu : transport.mtuSize;
|
|
2061
|
+
if (shouldRefreshNegotiatedMtu(transport.mtuSize)) {
|
|
2062
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleConnectedError, `Protocol V2 high-throughput BLE MTU unavailable: ${String(transport.mtuSize)}`);
|
|
2063
|
+
}
|
|
2064
|
+
});
|
|
2065
|
+
}
|
|
2066
|
+
clearAndroidPriorityResetTimer(uuid) {
|
|
2067
|
+
const timerId = this.androidPriorityResetTimers.get(uuid);
|
|
2068
|
+
if (timerId !== undefined) {
|
|
2069
|
+
clearTimeout(timerId);
|
|
2070
|
+
this.androidPriorityResetTimers.delete(uuid);
|
|
2071
|
+
}
|
|
2072
|
+
}
|
|
2073
|
+
enableAndroidHighConnectionPriority(uuid) {
|
|
2074
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2075
|
+
if (reactNative.Platform.OS !== 'android')
|
|
2076
|
+
return;
|
|
2077
|
+
this.clearAndroidPriorityResetTimer(uuid);
|
|
2078
|
+
if (this.androidHighPriorityDevices.has(uuid))
|
|
2079
|
+
return;
|
|
2080
|
+
const transport = transportCache[uuid];
|
|
2081
|
+
if (!transport)
|
|
2082
|
+
return;
|
|
2083
|
+
try {
|
|
2084
|
+
transport.device = yield transport.device.requestConnectionPriority(reactNativeBlePlx.ConnectionPriority.High);
|
|
2085
|
+
this.androidHighPriorityDevices.add(uuid);
|
|
2086
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Android BLE connection priority changed', {
|
|
2087
|
+
priority: 'high',
|
|
2088
|
+
});
|
|
2089
|
+
}
|
|
2090
|
+
catch (error) {
|
|
2091
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Android BLE high priority request failed', {
|
|
2092
|
+
error: error instanceof Error ? error.message : String(error),
|
|
2093
|
+
});
|
|
2094
|
+
}
|
|
2095
|
+
});
|
|
2096
|
+
}
|
|
2097
|
+
scheduleAndroidBalancedConnectionPriority(uuid) {
|
|
2098
|
+
if (reactNative.Platform.OS !== 'android' || !this.androidHighPriorityDevices.has(uuid))
|
|
2099
|
+
return;
|
|
2100
|
+
this.clearAndroidPriorityResetTimer(uuid);
|
|
2101
|
+
const timerId = setTimeout(() => {
|
|
2102
|
+
this.androidPriorityResetTimers.delete(uuid);
|
|
2103
|
+
this.restoreAndroidConnectionPriority(uuid, transportCache[uuid]).catch(error => Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Android BLE priority restore failed', error));
|
|
2104
|
+
}, ANDROID_HIGH_PRIORITY_IDLE_MS);
|
|
2105
|
+
this.androidPriorityResetTimers.set(uuid, timerId);
|
|
2106
|
+
}
|
|
2107
|
+
restoreAndroidConnectionPriority(uuid, transport) {
|
|
2108
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2109
|
+
this.clearAndroidPriorityResetTimer(uuid);
|
|
2110
|
+
if (reactNative.Platform.OS !== 'android' || !this.androidHighPriorityDevices.delete(uuid) || !transport) {
|
|
2111
|
+
return;
|
|
2112
|
+
}
|
|
2113
|
+
try {
|
|
2114
|
+
transport.device = yield transport.device.requestConnectionPriority(reactNativeBlePlx.ConnectionPriority.Balanced);
|
|
2115
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Android BLE connection priority changed', {
|
|
2116
|
+
priority: 'balanced',
|
|
2117
|
+
});
|
|
2118
|
+
}
|
|
2119
|
+
catch (error) {
|
|
2120
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Android BLE balanced priority request failed', {
|
|
2121
|
+
error: error instanceof Error ? error.message : String(error),
|
|
2122
|
+
});
|
|
2123
|
+
}
|
|
1557
2124
|
});
|
|
1558
2125
|
}
|
|
1559
2126
|
createProtocolV2Adapter(uuid) {
|
|
@@ -1574,10 +2141,10 @@ class ReactNativeBleTransport {
|
|
|
1574
2141
|
(_a = this.protocolV2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
|
|
1575
2142
|
this.resetProtocolV2Frames(uuid);
|
|
1576
2143
|
},
|
|
1577
|
-
writeFrame: (frame) => __awaiter(this, void 0, void 0, function* () {
|
|
2144
|
+
writeFrame: (frame, context) => __awaiter(this, void 0, void 0, function* () {
|
|
1578
2145
|
assertCurrentGeneration();
|
|
1579
2146
|
const currentTransport = this.getCachedTransport(uuid);
|
|
1580
|
-
yield this.writeProtocolV2Frame(currentTransport, frame);
|
|
2147
|
+
yield this.writeProtocolV2Frame(uuid, currentTransport, frame, context, assertCurrentGeneration);
|
|
1581
2148
|
}),
|
|
1582
2149
|
readFrame: () => __awaiter(this, void 0, void 0, function* () {
|
|
1583
2150
|
assertCurrentGeneration();
|
|
@@ -1589,6 +2156,8 @@ class ReactNativeBleTransport {
|
|
|
1589
2156
|
}),
|
|
1590
2157
|
reset: (reason) => {
|
|
1591
2158
|
var _a;
|
|
2159
|
+
if (this.monitorTokens.get(uuid) !== generation)
|
|
2160
|
+
return;
|
|
1592
2161
|
(_a = this.protocolV2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
|
|
1593
2162
|
this.rejectProtocolV2Frames(uuid, new Error(reason));
|
|
1594
2163
|
},
|
|
@@ -1598,11 +2167,19 @@ class ReactNativeBleTransport {
|
|
|
1598
2167
|
};
|
|
1599
2168
|
}
|
|
1600
2169
|
getProtocolType(path) {
|
|
1601
|
-
return this.
|
|
2170
|
+
return this.getActiveProtocol(path);
|
|
1602
2171
|
}
|
|
1603
2172
|
}
|
|
1604
2173
|
|
|
2174
|
+
exports.BLE_CONNECT_TIMEOUT_MANAGER_RESET_THRESHOLD = BLE_CONNECT_TIMEOUT_MANAGER_RESET_THRESHOLD;
|
|
2175
|
+
exports.BLE_CONNECT_TIMEOUT_MS = BLE_CONNECT_TIMEOUT_MS;
|
|
2176
|
+
exports.BLE_GATT_SETUP_TIMEOUT_MS = BLE_GATT_SETUP_TIMEOUT_MS;
|
|
2177
|
+
exports.BLE_NATIVE_TEARDOWN_TIMEOUT_MS = BLE_NATIVE_TEARDOWN_TIMEOUT_MS;
|
|
2178
|
+
exports.BLE_WRITE_PACKET_TIMEOUT_MS = BLE_WRITE_PACKET_TIMEOUT_MS;
|
|
2179
|
+
exports.BLE_WRITE_TIMEOUT_MANAGER_RESET_THRESHOLD = BLE_WRITE_TIMEOUT_MANAGER_RESET_THRESHOLD;
|
|
2180
|
+
exports.PROTOCOL_REPROBE_FALLBACK_ATTEMPTS = PROTOCOL_REPROBE_FALLBACK_ATTEMPTS;
|
|
1605
2181
|
exports.configureProtocolV2BleTuning = configureProtocolV2BleTuning;
|
|
1606
2182
|
exports["default"] = ReactNativeBleTransport;
|
|
2183
|
+
exports.getFirmwareUploadWriteRetryType = getFirmwareUploadWriteRetryType;
|
|
1607
2184
|
exports.getProtocolV2BleTuning = getProtocolV2BleTuning;
|
|
1608
2185
|
exports.resetProtocolV2BleTuning = resetProtocolV2BleTuning;
|