@onekeyfe/hd-transport-react-native 1.2.0-alpha.7 → 1.2.0-alpha.70
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 +1 -3
- package/dist/BleTransport.d.ts.map +1 -1
- package/dist/bleStrategy.d.ts +0 -2
- package/dist/bleStrategy.d.ts.map +1 -1
- package/dist/constants.d.ts +0 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/index.d.ts +99 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +705 -387
- package/dist/subscribeBleOn.d.ts.map +1 -1
- package/dist/transportLog.d.ts +2 -0
- package/dist/transportLog.d.ts.map +1 -0
- package/dist/types.d.ts +1 -0
- package/dist/types.d.ts.map +1 -1
- package/jest.config.js +10 -0
- package/package.json +7 -6
- package/src/BleTransport.ts +6 -41
- package/src/__tests__/BleTransport.test.ts +93 -0
- package/src/__tests__/bleStrategy.test.ts +1 -6
- package/src/__tests__/connectTimeout.test.ts +281 -0
- package/src/__tests__/constants.test.ts +20 -0
- package/src/__tests__/enumerate.test.ts +132 -0
- package/src/__tests__/protocolReprobe.test.ts +132 -0
- package/src/__tests__/protocolV1SchemaFixture.ts +39 -0
- package/src/__tests__/protocolV2Link.test.ts +769 -0
- package/src/__tests__/staleCallTimeout.test.ts +210 -0
- package/src/__tests__/writePacketTimeout.test.ts +305 -0
- package/src/bleStrategy.ts +0 -25
- package/src/constants.ts +7 -13
- package/src/index.ts +931 -408
- package/src/subscribeBleOn.ts +0 -2
- package/src/transportLog.ts +1 -0
- package/src/types.ts +1 -0
package/dist/index.js
CHANGED
|
@@ -117,42 +117,23 @@ const getInfosForServiceUuid = (serviceUuid, deviceType) => {
|
|
|
117
117
|
return null;
|
|
118
118
|
}
|
|
119
119
|
const normalizedServiceUuid = normalizeBleUuid(serviceUuid);
|
|
120
|
-
const service = (_a = services[serviceUuid]) !== null && _a !== void 0 ? _a : Object.values(services).find(item => normalizeBleUuid(item.serviceUuid) === normalizedServiceUuid
|
|
120
|
+
const service = (_a = services[serviceUuid]) !== null && _a !== void 0 ? _a : Object.values(services).find(item => normalizeBleUuid(item.serviceUuid) === normalizedServiceUuid ||
|
|
121
|
+
hdShared.matchesKnownBleUuid(serviceUuid, hdShared.createKnownBleUuidAliases(item.serviceUuid)));
|
|
121
122
|
if (!service) {
|
|
122
123
|
return null;
|
|
123
124
|
}
|
|
124
125
|
return service;
|
|
125
126
|
};
|
|
126
127
|
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
128
|
const isSameBleUuid = (left, right) => {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
return (
|
|
135
|
-
(getBleUuidKey(left) !== '' && getBleUuidKey(left) === getBleUuidKey(right)));
|
|
129
|
+
if (!left || !right)
|
|
130
|
+
return false;
|
|
131
|
+
return hdShared.matchesKnownBleUuid(left, hdShared.createKnownBleUuidAliases(right));
|
|
136
132
|
};
|
|
137
133
|
|
|
138
134
|
function hasWritableCapability(characteristic) {
|
|
139
135
|
return !!(characteristic.isWritableWithResponse || characteristic.isWritableWithoutResponse);
|
|
140
136
|
}
|
|
141
|
-
function resolveBleWriteMode(characteristic, preferredMode = 'withoutResponse') {
|
|
142
|
-
if (preferredMode === 'withoutResponse' && characteristic.isWritableWithoutResponse) {
|
|
143
|
-
return 'withoutResponse';
|
|
144
|
-
}
|
|
145
|
-
if (preferredMode === 'withResponse' && characteristic.isWritableWithResponse) {
|
|
146
|
-
return 'withResponse';
|
|
147
|
-
}
|
|
148
|
-
if (characteristic.isWritableWithoutResponse) {
|
|
149
|
-
return 'withoutResponse';
|
|
150
|
-
}
|
|
151
|
-
if (characteristic.isWritableWithResponse) {
|
|
152
|
-
return 'withResponse';
|
|
153
|
-
}
|
|
154
|
-
return preferredMode;
|
|
155
|
-
}
|
|
156
137
|
function resolveProtocolV2PacketCapacity({ platform, iosPacketLength = IOS_PACKET_LENGTH, androidPacketLength = ANDROID_PACKET_LENGTH, mtu, }) {
|
|
157
138
|
if (platform === 'ios') {
|
|
158
139
|
return iosPacketLength;
|
|
@@ -189,7 +170,6 @@ const timer = process.env.NODE_ENV === 'development'
|
|
|
189
170
|
const subscribeBleOn = (bleManager, ms = 1000) => new Promise((resolve, reject) => {
|
|
190
171
|
let done = false;
|
|
191
172
|
const subscription = bleManager.onStateChange(state => {
|
|
192
|
-
console.log('ble state -> ', state);
|
|
193
173
|
if (state === 'PoweredOn') {
|
|
194
174
|
if (done)
|
|
195
175
|
return;
|
|
@@ -219,7 +199,6 @@ const isHeaderChunk = (chunk) => {
|
|
|
219
199
|
return false;
|
|
220
200
|
};
|
|
221
201
|
|
|
222
|
-
const Log$1 = bleLogger;
|
|
223
202
|
class BleTransport {
|
|
224
203
|
constructor(device, writeCharacteristic, notifyCharacteristic) {
|
|
225
204
|
this.name = 'ReactNativeBleTransport';
|
|
@@ -229,37 +208,16 @@ class BleTransport {
|
|
|
229
208
|
this.writeCharacteristic = writeCharacteristic;
|
|
230
209
|
this.notifyCharacteristic = notifyCharacteristic;
|
|
231
210
|
}
|
|
232
|
-
writeWithRetry(data
|
|
211
|
+
writeWithRetry(data) {
|
|
233
212
|
return __awaiter(this, void 0, void 0, function* () {
|
|
234
|
-
|
|
235
|
-
yield this.writeCharacteristic.
|
|
236
|
-
|
|
237
|
-
catch (error) {
|
|
238
|
-
Log$1 === null || Log$1 === void 0 ? void 0 : Log$1.debug(`Write retry attempt ${BleTransport.MAX_RETRIES - retryCount + 1}, error: ${error}`);
|
|
239
|
-
if (retryCount > 0) {
|
|
240
|
-
yield hdShared.wait(BleTransport.RETRY_DELAY);
|
|
241
|
-
if (error.errorCode === reactNativeBlePlx.BleErrorCode.DeviceDisconnected ||
|
|
242
|
-
error.errorCode === reactNativeBlePlx.BleErrorCode.CharacteristicNotFound) {
|
|
243
|
-
try {
|
|
244
|
-
yield this.device.connect();
|
|
245
|
-
yield this.device.discoverAllServicesAndCharacteristics();
|
|
246
|
-
}
|
|
247
|
-
catch (e) {
|
|
248
|
-
Log$1 === null || Log$1 === void 0 ? void 0 : Log$1.debug(`Connect or discoverAllServicesAndCharacteristics error: ${e}`);
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
else {
|
|
252
|
-
Log$1 === null || Log$1 === void 0 ? void 0 : Log$1.debug(`writeCharacteristic error: ${error}`);
|
|
253
|
-
}
|
|
254
|
-
return this.writeWithRetry(data, retryCount - 1);
|
|
255
|
-
}
|
|
256
|
-
throw error;
|
|
213
|
+
if (reactNative.Platform.OS === 'ios' && this.writeCharacteristic.isWritableWithResponse) {
|
|
214
|
+
yield this.writeCharacteristic.writeWithResponse(data);
|
|
215
|
+
return;
|
|
257
216
|
}
|
|
217
|
+
yield this.writeCharacteristic.writeWithoutResponse(data);
|
|
258
218
|
});
|
|
259
219
|
}
|
|
260
220
|
}
|
|
261
|
-
BleTransport.MAX_RETRIES = 5;
|
|
262
|
-
BleTransport.RETRY_DELAY = 2000;
|
|
263
221
|
|
|
264
222
|
const { check, ProtocolV1, parseConfigure } = transport__default["default"];
|
|
265
223
|
const Log = bleLogger;
|
|
@@ -268,10 +226,36 @@ const FIRMWARE_UPLOAD_WRITE_BURST_SIZE = reactNative.Platform.OS === 'ios' ? 4 :
|
|
|
268
226
|
const FIRMWARE_UPLOAD_WRITE_PAUSE_MS = reactNative.Platform.OS === 'ios' ? 8 : 10;
|
|
269
227
|
const FIRMWARE_UPLOAD_WRITE_FLUSH_DELAY_MS = reactNative.Platform.OS === 'ios' ? 24 : 30;
|
|
270
228
|
const FIRMWARE_UPLOAD_WRITE_MAX_RETRIES = 8;
|
|
271
|
-
const
|
|
229
|
+
const IOS_PROTOCOL_V2_CONTROL_WRITE_DELAY_MS = 5;
|
|
272
230
|
const ANDROID_FIRMWARE_UPLOAD_PACKET_LENGTH = 192;
|
|
273
231
|
const FIRMWARE_UPLOAD_WRITE_PACKET_CAPACITY = reactNative.Platform.OS === 'ios' ? IOS_PACKET_LENGTH : ANDROID_FIRMWARE_UPLOAD_PACKET_LENGTH;
|
|
274
232
|
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
|
+
};
|
|
275
259
|
const delay = (ms) => new Promise(resolve => {
|
|
276
260
|
setTimeout(resolve, ms);
|
|
277
261
|
});
|
|
@@ -279,10 +263,6 @@ const getFirmwareUploadWriteRetryType = (error) => {
|
|
|
279
263
|
if (!error || typeof error !== 'object')
|
|
280
264
|
return null;
|
|
281
265
|
const bleWriteError = error;
|
|
282
|
-
if (bleWriteError.errorCode === reactNativeBlePlx.BleErrorCode.DeviceDisconnected ||
|
|
283
|
-
bleWriteError.errorCode === reactNativeBlePlx.BleErrorCode.CharacteristicNotFound) {
|
|
284
|
-
return 'reconnectable';
|
|
285
|
-
}
|
|
286
266
|
if (bleWriteError.androidErrorCode === ANDROID_GATT_CONGESTED_STATUS ||
|
|
287
267
|
bleWriteError.status === ANDROID_GATT_CONGESTED_STATUS) {
|
|
288
268
|
return 'congested';
|
|
@@ -290,25 +270,23 @@ const getFirmwareUploadWriteRetryType = (error) => {
|
|
|
290
270
|
const text = [bleWriteError.reason, bleWriteError.message, bleWriteError.name]
|
|
291
271
|
.filter(value => typeof value === 'string')
|
|
292
272
|
.join(' ');
|
|
293
|
-
return
|
|
273
|
+
return text.includes('GATT_CONGESTED') || hasGattCongestedStatus(text) ? 'congested' : null;
|
|
294
274
|
};
|
|
295
275
|
const resolveFirmwareUploadRetryDelay = (attempt, baseDelayMs = 200, maxDelayMs = 1200) => Math.min(baseDelayMs * Math.pow(2, attempt), maxDelayMs);
|
|
296
|
-
const BLE_RESPONSE_TIMEOUT_MS = 30000;
|
|
297
276
|
const PROTOCOL_PROBE_TIMEOUT_MS = 1000;
|
|
298
277
|
const PROTOCOL_V2_PROBE_TIMEOUT_MS = 10000;
|
|
299
|
-
const
|
|
278
|
+
const BLE_WRITE_PACKET_TIMEOUT_MS = 10000;
|
|
279
|
+
const WEDGED_WRITE_MESSAGE = 'BLE write timeout after';
|
|
280
|
+
const isWedgedWriteError = (error) => (error === null || error === void 0 ? void 0 : error.errorCode) === hdShared.HardwareErrorCode.BleWriteCharacteristicError &&
|
|
281
|
+
typeof (error === null || error === void 0 ? void 0 : error.message) === 'string' &&
|
|
282
|
+
error.message.startsWith(WEDGED_WRITE_MESSAGE);
|
|
283
|
+
const BLE_WRITE_TIMEOUT_MANAGER_RESET_THRESHOLD = 2;
|
|
284
|
+
const DEVICE_SCAN_TIMEOUT_MS = 3000;
|
|
300
285
|
const IOS_NOTIFY_READY_DELAY_MS = 150;
|
|
301
286
|
const ANDROID_NOTIFY_READY_DELAY_MS = 300;
|
|
302
|
-
const HIGH_VOLUME_WRITE_BURST_SIZE = reactNative.Platform.OS === 'ios' ? 4 : 6;
|
|
303
|
-
const HIGH_VOLUME_WRITE_PAUSE_MS = reactNative.Platform.OS === 'ios' ? 6 : 2;
|
|
304
|
-
const HIGH_VOLUME_WRITE_FLUSH_DELAY_MS = reactNative.Platform.OS === 'ios' ? 20 : 8;
|
|
305
287
|
const DEFAULT_PROTOCOL_V2_BLE_TUNING = {
|
|
306
288
|
iosPacketLength: IOS_PACKET_LENGTH,
|
|
307
289
|
androidPacketLength: ANDROID_PACKET_LENGTH,
|
|
308
|
-
highVolumeWriteBurstSize: HIGH_VOLUME_WRITE_BURST_SIZE,
|
|
309
|
-
highVolumeWritePauseMs: HIGH_VOLUME_WRITE_PAUSE_MS,
|
|
310
|
-
highVolumeWriteFlushDelayMs: HIGH_VOLUME_WRITE_FLUSH_DELAY_MS,
|
|
311
|
-
highVolumeWriteWithResponse: false,
|
|
312
290
|
};
|
|
313
291
|
let protocolV2BleTuning = Object.assign({}, DEFAULT_PROTOCOL_V2_BLE_TUNING);
|
|
314
292
|
const normalizePositiveInteger = (value, fallback) => {
|
|
@@ -318,20 +296,15 @@ const normalizePositiveInteger = (value, fallback) => {
|
|
|
318
296
|
return Math.floor(normalized);
|
|
319
297
|
};
|
|
320
298
|
function configureProtocolV2BleTuning(tuning = {}) {
|
|
321
|
-
var _a;
|
|
322
299
|
protocolV2BleTuning = {
|
|
323
300
|
iosPacketLength: normalizePositiveInteger(tuning.iosPacketLength, protocolV2BleTuning.iosPacketLength),
|
|
324
301
|
androidPacketLength: normalizePositiveInteger(tuning.androidPacketLength, protocolV2BleTuning.androidPacketLength),
|
|
325
|
-
highVolumeWriteBurstSize: normalizePositiveInteger(tuning.highVolumeWriteBurstSize, protocolV2BleTuning.highVolumeWriteBurstSize),
|
|
326
|
-
highVolumeWritePauseMs: normalizePositiveInteger(tuning.highVolumeWritePauseMs, protocolV2BleTuning.highVolumeWritePauseMs),
|
|
327
|
-
highVolumeWriteFlushDelayMs: normalizePositiveInteger(tuning.highVolumeWriteFlushDelayMs, protocolV2BleTuning.highVolumeWriteFlushDelayMs),
|
|
328
|
-
highVolumeWriteWithResponse: (_a = tuning.highVolumeWriteWithResponse) !== null && _a !== void 0 ? _a : protocolV2BleTuning.highVolumeWriteWithResponse,
|
|
329
302
|
};
|
|
330
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport]
|
|
303
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] BLE tuning configured', protocolV2BleTuning);
|
|
331
304
|
}
|
|
332
305
|
function resetProtocolV2BleTuning() {
|
|
333
306
|
protocolV2BleTuning = Object.assign({}, DEFAULT_PROTOCOL_V2_BLE_TUNING);
|
|
334
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport]
|
|
307
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] BLE tuning reset', protocolV2BleTuning);
|
|
335
308
|
}
|
|
336
309
|
function getProtocolV2BleTuning() {
|
|
337
310
|
return Object.assign({}, protocolV2BleTuning);
|
|
@@ -342,19 +315,25 @@ function inferProtocolHintFromDeviceName(name) {
|
|
|
342
315
|
function getDeviceDisplayName(device) {
|
|
343
316
|
return (device === null || device === void 0 ? void 0 : device.name) || (device === null || device === void 0 ? void 0 : device.localName) || null;
|
|
344
317
|
}
|
|
345
|
-
function isGenericBleService(uuid) {
|
|
346
|
-
return ['1800', '1801', '180a'].includes(getBleUuidKey(uuid));
|
|
347
|
-
}
|
|
348
|
-
function hasKnownOneKeyService(device) {
|
|
349
|
-
var _a;
|
|
350
|
-
return ((_a = device === null || device === void 0 ? void 0 : device.serviceUUIDs) !== null && _a !== void 0 ? _a : []).some(serviceUuid => getInfosForServiceUuid(serviceUuid, 'classic'));
|
|
351
|
-
}
|
|
352
318
|
const ANDROID_REQUEST_MTU = 256;
|
|
319
|
+
const BLE_NATIVE_CONNECT_TIMEOUT_MS = 3000;
|
|
353
320
|
const connectOptions = {
|
|
354
321
|
requestMTU: ANDROID_REQUEST_MTU,
|
|
355
|
-
timeout:
|
|
322
|
+
timeout: BLE_NATIVE_CONNECT_TIMEOUT_MS,
|
|
356
323
|
refreshGatt: 'OnConnected',
|
|
357
324
|
};
|
|
325
|
+
const fallbackConnectOptions = {
|
|
326
|
+
timeout: BLE_NATIVE_CONNECT_TIMEOUT_MS,
|
|
327
|
+
};
|
|
328
|
+
const BLE_CONNECT_TIMEOUT_MS = BLE_NATIVE_CONNECT_TIMEOUT_MS * 2 + 2000;
|
|
329
|
+
const BLE_GATT_SETUP_TIMEOUT_MS = 10000;
|
|
330
|
+
const PROTOCOL_REPROBE_FALLBACK_ATTEMPTS = 3;
|
|
331
|
+
const BLE_CONNECT_TIMEOUT_MANAGER_RESET_THRESHOLD = 2;
|
|
332
|
+
const CONNECT_TIMEOUT_MESSAGE = 'BLE connect timeout after';
|
|
333
|
+
const isConnectTimeoutError = (error) => (error === null || error === void 0 ? void 0 : error.errorCode) === hdShared.HardwareErrorCode.BleConnectedError &&
|
|
334
|
+
typeof (error === null || error === void 0 ? void 0 : error.message) === 'string' &&
|
|
335
|
+
error.message.startsWith(CONNECT_TIMEOUT_MESSAGE);
|
|
336
|
+
const isNativeOperationTimeoutError = (error) => (error === null || error === void 0 ? void 0 : error.errorCode) === reactNativeBlePlx.BleErrorCode.OperationTimedOut;
|
|
358
337
|
const tryToGetConfiguration = (device) => {
|
|
359
338
|
if (!device || !device.serviceUUIDs)
|
|
360
339
|
return null;
|
|
@@ -371,9 +350,10 @@ const requestAndroidMtu = (device) => __awaiter(void 0, void 0, void 0, function
|
|
|
371
350
|
return device;
|
|
372
351
|
try {
|
|
373
352
|
const mtuDevice = yield device.requestMTU(ANDROID_REQUEST_MTU);
|
|
374
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport]
|
|
353
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] MTU configured', {
|
|
354
|
+
deviceId: device.id,
|
|
375
355
|
requested: ANDROID_REQUEST_MTU,
|
|
376
|
-
|
|
356
|
+
actual: mtuDevice.mtu,
|
|
377
357
|
});
|
|
378
358
|
return mtuDevice;
|
|
379
359
|
}
|
|
@@ -408,15 +388,41 @@ class ReactNativeBleTransport {
|
|
|
408
388
|
this.stopped = false;
|
|
409
389
|
this.scanTimeout = DEVICE_SCAN_TIMEOUT_MS;
|
|
410
390
|
this.runPromise = null;
|
|
391
|
+
this.runPromiseDeviceId = null;
|
|
411
392
|
this.firmwareUploadWriteRecoveryIds = new Set();
|
|
412
393
|
this.deviceProtocol = new Map();
|
|
394
|
+
this.probingProtocols = new Map();
|
|
395
|
+
this.writeTimeoutCounts = new Map();
|
|
396
|
+
this.connectionSetupTimeoutCounts = new Map();
|
|
413
397
|
this.deviceProtocolHints = new Map();
|
|
398
|
+
this.sessionProtocols = new Map();
|
|
399
|
+
this.protocolReprobeFailures = new Map();
|
|
414
400
|
this.protocolV2Assemblers = new Map();
|
|
415
401
|
this.protocolV2FrameQueues = new Map();
|
|
416
402
|
this.protocolV2FramePromises = new Map();
|
|
417
|
-
this.
|
|
418
|
-
|
|
403
|
+
this.protocolV2Links = new transport.ProtocolV2LinkManager({
|
|
404
|
+
getSchemas: () => {
|
|
405
|
+
if (!this._messages || !this._messagesV2) {
|
|
406
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.TransportNotConfigured);
|
|
407
|
+
}
|
|
408
|
+
return {
|
|
409
|
+
protocolV1: this._messages,
|
|
410
|
+
protocolV2: this._messagesV2,
|
|
411
|
+
};
|
|
412
|
+
},
|
|
413
|
+
classifyError: () => 'link-fatal',
|
|
414
|
+
onLinkInvalidated: (uuid, reason) => __awaiter(this, void 0, void 0, function* () {
|
|
415
|
+
var _b;
|
|
416
|
+
(_b = this.protocolV2Assemblers.get(uuid)) === null || _b === void 0 ? void 0 : _b.reset();
|
|
417
|
+
this.rejectProtocolV2Frames(uuid, new Error(reason));
|
|
418
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V2 link invalidated:', uuid, reason);
|
|
419
|
+
if (reason.startsWith('Protocol V2 link-fatal error:')) {
|
|
420
|
+
yield this.releaseNative(uuid, true);
|
|
421
|
+
}
|
|
422
|
+
}),
|
|
423
|
+
});
|
|
419
424
|
this.monitorTokens = new Map();
|
|
425
|
+
this.disconnectEventTokens = new Map();
|
|
420
426
|
this.nextMonitorToken = 1;
|
|
421
427
|
this.scanTimeout = (_a = options.scanTimeout) !== null && _a !== void 0 ? _a : DEVICE_SCAN_TIMEOUT_MS;
|
|
422
428
|
}
|
|
@@ -430,8 +436,18 @@ class ReactNativeBleTransport {
|
|
|
430
436
|
this._messages = messages;
|
|
431
437
|
}
|
|
432
438
|
configureProtocolV2(signedData) {
|
|
439
|
+
const configuration = typeof signedData === 'string' ? signedData : JSON.stringify(signedData);
|
|
440
|
+
if (this.protocolV2SchemaConfiguration === configuration) {
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
443
|
+
const isReconfiguration = this.protocolV2SchemaConfiguration !== undefined;
|
|
433
444
|
this._messagesV2 = parseConfigure(signedData);
|
|
434
|
-
|
|
445
|
+
this.protocolV2SchemaConfiguration = configuration;
|
|
446
|
+
if (isReconfiguration) {
|
|
447
|
+
this.protocolV2Links
|
|
448
|
+
.invalidateAllLinks('Protocol V2 schema reconfigured')
|
|
449
|
+
.catch(error => Log === null || Log === void 0 ? void 0 : Log.debug('Protocol V2 schema link cleanup failed:', error));
|
|
450
|
+
}
|
|
435
451
|
}
|
|
436
452
|
listen() {
|
|
437
453
|
}
|
|
@@ -442,7 +458,6 @@ class ReactNativeBleTransport {
|
|
|
442
458
|
return Promise.resolve(this.blePlxManager);
|
|
443
459
|
}
|
|
444
460
|
resolveCharacteristics(device) {
|
|
445
|
-
var _a, _b, _c, _d;
|
|
446
461
|
return __awaiter(this, void 0, void 0, function* () {
|
|
447
462
|
yield device.discoverAllServicesAndCharacteristics();
|
|
448
463
|
let infos = tryToGetConfiguration(device);
|
|
@@ -459,19 +474,11 @@ class ReactNativeBleTransport {
|
|
|
459
474
|
}
|
|
460
475
|
}
|
|
461
476
|
}
|
|
462
|
-
let fallbackServiceUuid;
|
|
463
477
|
if (!infos) {
|
|
464
478
|
const services = yield device.services();
|
|
465
479
|
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));
|
|
466
|
-
const knownService = services.find(service => getInfosForServiceUuid(service.uuid, 'classic'));
|
|
467
|
-
const fallbackService = (_a = knownService !== null && knownService !== void 0 ? knownService : services.find(service => !isGenericBleService(service.uuid))) !== null && _a !== void 0 ? _a : services[0];
|
|
468
|
-
if (fallbackService) {
|
|
469
|
-
fallbackServiceUuid = fallbackService.uuid;
|
|
470
|
-
characteristics = yield device.characteristicsForService(fallbackService.uuid);
|
|
471
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Using fallback BLE service:', fallbackService.uuid);
|
|
472
|
-
}
|
|
473
480
|
}
|
|
474
|
-
if (!infos
|
|
481
|
+
if (!infos) {
|
|
475
482
|
try {
|
|
476
483
|
Log === null || Log === void 0 ? void 0 : Log.debug('cancel connection when service not found');
|
|
477
484
|
yield device.cancelConnection();
|
|
@@ -481,9 +488,7 @@ class ReactNativeBleTransport {
|
|
|
481
488
|
}
|
|
482
489
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleServiceNotFound);
|
|
483
490
|
}
|
|
484
|
-
const serviceUuid
|
|
485
|
-
const writeUuid = (_c = infos === null || infos === void 0 ? void 0 : infos.writeUuid) !== null && _c !== void 0 ? _c : '00000002-0000-1000-8000-00805f9b34fb';
|
|
486
|
-
const notifyUuid = (_d = infos === null || infos === void 0 ? void 0 : infos.notifyUuid) !== null && _d !== void 0 ? _d : '00000003-0000-1000-8000-00805f9b34fb';
|
|
491
|
+
const { serviceUuid, writeUuid, notifyUuid } = infos;
|
|
487
492
|
if (!serviceUuid) {
|
|
488
493
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleServiceNotFound);
|
|
489
494
|
}
|
|
@@ -524,8 +529,8 @@ class ReactNativeBleTransport {
|
|
|
524
529
|
attachDisconnectSubscription(transport, device, uuid) {
|
|
525
530
|
var _a;
|
|
526
531
|
(_a = transport.disconnectSubscription) === null || _a === void 0 ? void 0 : _a.remove();
|
|
532
|
+
const { monitorToken } = transport;
|
|
527
533
|
transport.disconnectSubscription = device.onDisconnected(() => {
|
|
528
|
-
var _a;
|
|
529
534
|
if (this.firmwareUploadWriteRecoveryIds.has(uuid)) {
|
|
530
535
|
Log === null || Log === void 0 ? void 0 : Log.debug('device disconnect ignored during FirmwareUpload write recovery: ', uuid);
|
|
531
536
|
return;
|
|
@@ -534,17 +539,16 @@ class ReactNativeBleTransport {
|
|
|
534
539
|
Log === null || Log === void 0 ? void 0 : Log.debug('device disconnect ignored for stale transport: ', device === null || device === void 0 ? void 0 : device.id);
|
|
535
540
|
return;
|
|
536
541
|
}
|
|
542
|
+
if (this.monitorTokens.get(uuid) !== monitorToken) {
|
|
543
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('device disconnect ignored for stale generation: ', device === null || device === void 0 ? void 0 : device.id);
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
537
546
|
try {
|
|
538
547
|
Log === null || Log === void 0 ? void 0 : Log.debug('device disconnect: ', device === null || device === void 0 ? void 0 : device.id);
|
|
539
|
-
(
|
|
540
|
-
|
|
541
|
-
id: device === null || device === void 0 ? void 0 : device.id,
|
|
542
|
-
connectId: device === null || device === void 0 ? void 0 : device.id,
|
|
543
|
-
});
|
|
544
|
-
if (this.runPromise) {
|
|
548
|
+
this.emitDeviceDisconnect(uuid, device === null || device === void 0 ? void 0 : device.name, monitorToken);
|
|
549
|
+
if (this.runPromise && this.runPromiseDeviceId === uuid) {
|
|
545
550
|
const error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleConnectedError);
|
|
546
551
|
this.runPromise.reject(error);
|
|
547
|
-
this.rejectAllProtocolV2Frames(error);
|
|
548
552
|
}
|
|
549
553
|
}
|
|
550
554
|
catch (e) {
|
|
@@ -555,6 +559,22 @@ class ReactNativeBleTransport {
|
|
|
555
559
|
}
|
|
556
560
|
});
|
|
557
561
|
}
|
|
562
|
+
emitDeviceDisconnect(uuid, name, token) {
|
|
563
|
+
var _a;
|
|
564
|
+
if (token === undefined || this.disconnectEventTokens.get(uuid) === token) {
|
|
565
|
+
return;
|
|
566
|
+
}
|
|
567
|
+
if (this.monitorTokens.get(uuid) !== token) {
|
|
568
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('device disconnect event ignored for stale generation: ', uuid);
|
|
569
|
+
return;
|
|
570
|
+
}
|
|
571
|
+
this.disconnectEventTokens.set(uuid, token);
|
|
572
|
+
(_a = this.emitter) === null || _a === void 0 ? void 0 : _a.emit(transport.TRANSPORT_EVENT.DEVICE_DISCONNECT, {
|
|
573
|
+
name,
|
|
574
|
+
id: uuid,
|
|
575
|
+
connectId: uuid,
|
|
576
|
+
});
|
|
577
|
+
}
|
|
558
578
|
reconnectFirmwareUploadTransport(uuid, transport) {
|
|
559
579
|
var _a, _b;
|
|
560
580
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -568,19 +588,19 @@ class ReactNativeBleTransport {
|
|
|
568
588
|
const isConnected = yield device.isConnected().catch(() => false);
|
|
569
589
|
if (!isConnected) {
|
|
570
590
|
try {
|
|
571
|
-
device = yield device.connect(connectOptions);
|
|
591
|
+
device = yield this.connectWithTimeout(uuid, () => device.connect(connectOptions));
|
|
572
592
|
}
|
|
573
593
|
catch (e) {
|
|
574
594
|
if (e.errorCode === reactNativeBlePlx.BleErrorCode.DeviceMTUChangeFailed ||
|
|
575
595
|
e.errorCode === reactNativeBlePlx.BleErrorCode.OperationCancelled) {
|
|
576
|
-
device = yield device.connect();
|
|
596
|
+
device = yield this.connectWithTimeout(uuid, () => device.connect());
|
|
577
597
|
}
|
|
578
598
|
else if (e.errorCode !== reactNativeBlePlx.BleErrorCode.DeviceAlreadyConnected) {
|
|
579
599
|
throw e;
|
|
580
600
|
}
|
|
581
601
|
}
|
|
582
602
|
}
|
|
583
|
-
const { writeCharacteristic, notifyCharacteristic } = yield this.
|
|
603
|
+
const { writeCharacteristic, notifyCharacteristic } = yield this.resolveCharacteristicsWithTimeout(uuid, device);
|
|
584
604
|
transport.device = device;
|
|
585
605
|
transport.writeCharacteristic = writeCharacteristic;
|
|
586
606
|
transport.notifyCharacteristic = notifyCharacteristic;
|
|
@@ -624,13 +644,12 @@ class ReactNativeBleTransport {
|
|
|
624
644
|
return;
|
|
625
645
|
}
|
|
626
646
|
}
|
|
627
|
-
blePlxManager.startDeviceScan(
|
|
647
|
+
blePlxManager.startDeviceScan(getBluetoothServiceUuids(), {
|
|
628
648
|
allowDuplicates: true,
|
|
629
649
|
scanMode: reactNativeBlePlx.ScanMode.LowLatency,
|
|
630
650
|
}, (error, device) => {
|
|
631
|
-
var _a
|
|
651
|
+
var _a;
|
|
632
652
|
if (error) {
|
|
633
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('ble scan manager: ', blePlxManager);
|
|
634
653
|
Log === null || Log === void 0 ? void 0 : Log.debug('ble scan error: ', error);
|
|
635
654
|
if ([reactNativeBlePlx.BleErrorCode.BluetoothPoweredOff, reactNativeBlePlx.BleErrorCode.BluetoothInUnknownState].includes(error.errorCode)) {
|
|
636
655
|
reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BlePermissionError));
|
|
@@ -650,25 +669,19 @@ class ReactNativeBleTransport {
|
|
|
650
669
|
return;
|
|
651
670
|
}
|
|
652
671
|
const displayName = getDeviceDisplayName(device);
|
|
653
|
-
const
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
const
|
|
657
|
-
|
|
658
|
-
|
|
672
|
+
const isUnnamedIOSPeripheral = reactNative.Platform.OS === 'ios' && !(displayName === null || displayName === void 0 ? void 0 : displayName.trim());
|
|
673
|
+
const isFindMyPeripheral = hdShared.isPro2FindMyAdvertisementName(device === null || device === void 0 ? void 0 : device.name) ||
|
|
674
|
+
hdShared.isPro2FindMyAdvertisementName(device === null || device === void 0 ? void 0 : device.localName);
|
|
675
|
+
const isOneKey = !isUnnamedIOSPeripheral &&
|
|
676
|
+
!isFindMyPeripheral &&
|
|
677
|
+
hdShared.isOnekeyBluetoothDevice({
|
|
678
|
+
id: device === null || device === void 0 ? void 0 : device.id,
|
|
659
679
|
name: device === null || device === void 0 ? void 0 : device.name,
|
|
660
680
|
localName: device === null || device === void 0 ? void 0 : device.localName,
|
|
661
|
-
|
|
662
|
-
serviceUUIDs: device === null || device === void 0 ? void 0 : device.serviceUUIDs,
|
|
663
|
-
accepted: isOneKey,
|
|
681
|
+
serviceUuids: device === null || device === void 0 ? void 0 : device.serviceUUIDs,
|
|
664
682
|
});
|
|
665
|
-
}
|
|
666
683
|
if (isOneKey) {
|
|
667
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('search device start ======================');
|
|
668
|
-
const { name, localName, id, serviceUUIDs } = device !== null && device !== void 0 ? device : {};
|
|
669
|
-
Log === null || Log === void 0 ? void 0 : Log.debug(`device name: ${name !== null && name !== void 0 ? name : ''}\nlocalName: ${localName !== null && localName !== void 0 ? localName : ''}\nid: ${id !== null && id !== void 0 ? id : ''}\nserviceUUIDs: ${(serviceUUIDs !== null && serviceUUIDs !== void 0 ? serviceUUIDs : []).join(',')}`);
|
|
670
684
|
addDevice(device);
|
|
671
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('search device end ======================\n');
|
|
672
685
|
}
|
|
673
686
|
else if (displayName && /\bpro\s*2\b/i.test(displayName)) {
|
|
674
687
|
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Pro2-like BLE device was not accepted:', {
|
|
@@ -679,10 +692,23 @@ class ReactNativeBleTransport {
|
|
|
679
692
|
});
|
|
680
693
|
}
|
|
681
694
|
});
|
|
682
|
-
getConnectedDeviceIds(getBluetoothServiceUuids()).then(devices => {
|
|
695
|
+
getConnectedDeviceIds(reactNative.Platform.OS === 'ios' ? getBluetoothServiceUuids() : []).then(devices => {
|
|
683
696
|
for (const device of devices) {
|
|
684
|
-
|
|
685
|
-
|
|
697
|
+
const localName = 'localName' in device && typeof device.localName === 'string'
|
|
698
|
+
? device.localName
|
|
699
|
+
: null;
|
|
700
|
+
const isFindMyPeripheral = hdShared.isPro2FindMyAdvertisementName(device.name) ||
|
|
701
|
+
hdShared.isPro2FindMyAdvertisementName(localName);
|
|
702
|
+
if (!isFindMyPeripheral &&
|
|
703
|
+
hdShared.isOnekeyBluetoothDevice({
|
|
704
|
+
id: device.id,
|
|
705
|
+
name: device.name,
|
|
706
|
+
localName,
|
|
707
|
+
serviceUuids: device.serviceUUIDs,
|
|
708
|
+
})) {
|
|
709
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('search connected peripheral: ', device.id);
|
|
710
|
+
addDevice(device);
|
|
711
|
+
}
|
|
686
712
|
}
|
|
687
713
|
});
|
|
688
714
|
const addDevice = (device) => {
|
|
@@ -694,6 +720,12 @@ class ReactNativeBleTransport {
|
|
|
694
720
|
this.deviceProtocolHints.set(device.id, protocolHint);
|
|
695
721
|
}
|
|
696
722
|
deviceList.push(Object.assign(Object.assign({}, device), { name: displayName, commType: 'ble' }));
|
|
723
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] OneKey BLE device discovered', {
|
|
724
|
+
deviceId: device.id,
|
|
725
|
+
name: displayName,
|
|
726
|
+
serviceUUIDs: device.serviceUUIDs,
|
|
727
|
+
protocolHint,
|
|
728
|
+
});
|
|
697
729
|
}
|
|
698
730
|
};
|
|
699
731
|
timer.timeout(() => {
|
|
@@ -703,6 +735,33 @@ class ReactNativeBleTransport {
|
|
|
703
735
|
}));
|
|
704
736
|
});
|
|
705
737
|
}
|
|
738
|
+
installTransportForAcquire(uuid, device, characteristics) {
|
|
739
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
740
|
+
const { writeCharacteristic, notifyCharacteristic } = characteristics !== null && characteristics !== void 0 ? characteristics : (yield this.resolveCharacteristicsWithTimeout(uuid, device));
|
|
741
|
+
const transport$1 = new BleTransport(device, writeCharacteristic, notifyCharacteristic);
|
|
742
|
+
if (reactNative.Platform.OS === 'android') {
|
|
743
|
+
transport$1.mtuSize = typeof device.mtu === 'number' ? device.mtu : transport$1.mtuSize;
|
|
744
|
+
}
|
|
745
|
+
const monitorToken = this.nextMonitorToken;
|
|
746
|
+
this.nextMonitorToken += 1;
|
|
747
|
+
const notifyTransactionId = `${uuid}:notify:${monitorToken}`;
|
|
748
|
+
transport$1.monitorToken = monitorToken;
|
|
749
|
+
transport$1.notifyTransactionId = notifyTransactionId;
|
|
750
|
+
this.monitorTokens.set(uuid, monitorToken);
|
|
751
|
+
transport$1.notifySubscription = this._monitorCharacteristic(transport$1.notifyCharacteristic, uuid, monitorToken, notifyTransactionId);
|
|
752
|
+
transportCache[uuid] = transport$1;
|
|
753
|
+
this.protocolV2Assemblers.set(uuid, new transport.ProtocolV2FrameAssembler(transport.PROTOCOL_V2_BLE_FRAME_MAX_BYTES));
|
|
754
|
+
if (reactNative.Platform.OS === 'ios') {
|
|
755
|
+
yield new Promise(resolve => {
|
|
756
|
+
setTimeout(resolve, IOS_NOTIFY_READY_DELAY_MS);
|
|
757
|
+
});
|
|
758
|
+
}
|
|
759
|
+
else if (reactNative.Platform.OS === 'android') {
|
|
760
|
+
yield delay(ANDROID_NOTIFY_READY_DELAY_MS);
|
|
761
|
+
}
|
|
762
|
+
return transport$1;
|
|
763
|
+
});
|
|
764
|
+
}
|
|
706
765
|
acquire(input) {
|
|
707
766
|
var _a, _b;
|
|
708
767
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -727,9 +786,8 @@ class ReactNativeBleTransport {
|
|
|
727
786
|
if (forceCleanRunPromise && this.runPromise) {
|
|
728
787
|
const error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleForceCleanRunPromise);
|
|
729
788
|
this.runPromise.reject(error);
|
|
730
|
-
this.rejectAllProtocolV2Frames(error);
|
|
731
789
|
this.runPromise = null;
|
|
732
|
-
this.
|
|
790
|
+
this.runPromiseDeviceId = null;
|
|
733
791
|
Log === null || Log === void 0 ? void 0 : Log.debug('Force clean Bluetooth run promise, forceCleanRunPromise: ', forceCleanRunPromise);
|
|
734
792
|
}
|
|
735
793
|
const blePlxManager = yield this.getPlxManager();
|
|
@@ -762,14 +820,17 @@ class ReactNativeBleTransport {
|
|
|
762
820
|
if (!device) {
|
|
763
821
|
Log === null || Log === void 0 ? void 0 : Log.debug('try to connect to device: ', uuid);
|
|
764
822
|
try {
|
|
765
|
-
device = yield blePlxManager.connectToDevice(uuid, connectOptions);
|
|
823
|
+
device = yield this.connectWithTimeout(uuid, () => blePlxManager.connectToDevice(uuid, connectOptions));
|
|
766
824
|
}
|
|
767
825
|
catch (e) {
|
|
768
826
|
Log === null || Log === void 0 ? void 0 : Log.debug('try to connect to device has error: ', e);
|
|
827
|
+
if (isConnectTimeoutError(e)) {
|
|
828
|
+
throw e;
|
|
829
|
+
}
|
|
769
830
|
if (e.errorCode === reactNativeBlePlx.BleErrorCode.DeviceMTUChangeFailed ||
|
|
770
831
|
e.errorCode === reactNativeBlePlx.BleErrorCode.OperationCancelled) {
|
|
771
832
|
Log === null || Log === void 0 ? void 0 : Log.debug('first try to reconnect without params');
|
|
772
|
-
device = yield blePlxManager.connectToDevice(uuid);
|
|
833
|
+
device = yield this.connectWithTimeout(uuid, () => blePlxManager.connectToDevice(uuid, fallbackConnectOptions));
|
|
773
834
|
}
|
|
774
835
|
else if (e.errorCode === reactNativeBlePlx.BleErrorCode.DeviceAlreadyConnected) {
|
|
775
836
|
Log === null || Log === void 0 ? void 0 : Log.debug('device already connected');
|
|
@@ -785,23 +846,27 @@ class ReactNativeBleTransport {
|
|
|
785
846
|
}
|
|
786
847
|
if (!(yield device.isConnected())) {
|
|
787
848
|
Log === null || Log === void 0 ? void 0 : Log.debug('not connected, try to connect to device: ', uuid);
|
|
849
|
+
const disconnectedDevice = device;
|
|
788
850
|
try {
|
|
789
|
-
device = yield
|
|
851
|
+
device = yield this.connectWithTimeout(uuid, () => disconnectedDevice.connect(connectOptions));
|
|
790
852
|
}
|
|
791
853
|
catch (e) {
|
|
792
854
|
Log === null || Log === void 0 ? void 0 : Log.debug('not connected, try to connect to device has error: ', e);
|
|
855
|
+
if (isConnectTimeoutError(e)) {
|
|
856
|
+
throw e;
|
|
857
|
+
}
|
|
793
858
|
if (e.errorCode === reactNativeBlePlx.BleErrorCode.DeviceMTUChangeFailed ||
|
|
794
859
|
e.errorCode === reactNativeBlePlx.BleErrorCode.OperationCancelled) {
|
|
795
860
|
Log === null || Log === void 0 ? void 0 : Log.debug('second try to reconnect without params');
|
|
796
861
|
try {
|
|
797
|
-
device = yield
|
|
862
|
+
device = yield this.connectWithTimeout(uuid, () => disconnectedDevice.connect(fallbackConnectOptions));
|
|
798
863
|
}
|
|
799
864
|
catch (e) {
|
|
800
865
|
Log === null || Log === void 0 ? void 0 : Log.debug('last try to reconnect error: ', e);
|
|
801
866
|
if (e.errorCode === reactNativeBlePlx.BleErrorCode.OperationCancelled) {
|
|
802
867
|
Log === null || Log === void 0 ? void 0 : Log.debug('last try to reconnect');
|
|
803
|
-
yield
|
|
804
|
-
device = yield
|
|
868
|
+
yield disconnectedDevice.cancelConnection();
|
|
869
|
+
device = yield this.connectWithTimeout(uuid, () => disconnectedDevice.connect(fallbackConnectOptions));
|
|
805
870
|
}
|
|
806
871
|
}
|
|
807
872
|
}
|
|
@@ -811,50 +876,41 @@ class ReactNativeBleTransport {
|
|
|
811
876
|
}
|
|
812
877
|
}
|
|
813
878
|
device = yield requestAndroidMtu(device);
|
|
814
|
-
const
|
|
879
|
+
const acquiredDevice = device;
|
|
880
|
+
const { writeCharacteristic, notifyCharacteristic } = yield this.resolveCharacteristicsWithTimeout(uuid, acquiredDevice);
|
|
815
881
|
const protocolHint = expectedProtocol
|
|
816
882
|
? undefined
|
|
817
|
-
: (_a = this.deviceProtocolHints.get(uuid)) !== null &&
|
|
883
|
+
: (_b = (_a = input.protocolHint) !== null && _a !== void 0 ? _a : this.deviceProtocolHints.get(uuid)) !== null && _b !== void 0 ? _b : inferProtocolHintFromDeviceName(getDeviceDisplayName(acquiredDevice));
|
|
818
884
|
yield this.release(uuid, true);
|
|
819
885
|
if (protocolHint) {
|
|
820
886
|
this.deviceProtocolHints.set(uuid, protocolHint);
|
|
821
887
|
}
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
yield new Promise(resolve => {
|
|
837
|
-
setTimeout(resolve, IOS_NOTIFY_READY_DELAY_MS);
|
|
838
|
-
});
|
|
888
|
+
yield this.installTransportForAcquire(uuid, acquiredDevice, {
|
|
889
|
+
writeCharacteristic,
|
|
890
|
+
notifyCharacteristic,
|
|
891
|
+
});
|
|
892
|
+
try {
|
|
893
|
+
const protocolType = yield this.detectProtocol(uuid, expectedProtocol, protocolHint, () => __awaiter(this, void 0, void 0, function* () {
|
|
894
|
+
yield this.installTransportForAcquire(uuid, acquiredDevice);
|
|
895
|
+
}));
|
|
896
|
+
const currentTransport = transportCache[uuid];
|
|
897
|
+
if (!currentTransport) {
|
|
898
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.TransportNotFound);
|
|
899
|
+
}
|
|
900
|
+
this.attachDisconnectSubscription(currentTransport, acquiredDevice, uuid);
|
|
901
|
+
return { uuid, protocolType };
|
|
839
902
|
}
|
|
840
|
-
|
|
841
|
-
yield
|
|
903
|
+
catch (error) {
|
|
904
|
+
yield this.release(uuid, true);
|
|
905
|
+
throw error;
|
|
842
906
|
}
|
|
843
|
-
const protocolType = yield this.detectProtocol(uuid, expectedProtocol, protocolHint);
|
|
844
|
-
(_b = this.emitter) === null || _b === void 0 ? void 0 : _b.emit('device-connect', {
|
|
845
|
-
name: device.name,
|
|
846
|
-
id: device.id,
|
|
847
|
-
connectId: device.id,
|
|
848
|
-
});
|
|
849
|
-
this.attachDisconnectSubscription(transport$1, device, uuid);
|
|
850
|
-
return { uuid, protocolType };
|
|
851
907
|
});
|
|
852
908
|
}
|
|
853
909
|
_monitorCharacteristic(characteristic, uuid, monitorToken, notifyTransactionId) {
|
|
854
910
|
let bufferLength = 0;
|
|
855
911
|
let buffer$1 = [];
|
|
856
912
|
const subscription = characteristic.monitor((error, c) => {
|
|
857
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
913
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
|
|
858
914
|
const isCurrentMonitor = this.monitorTokens.get(uuid) === monitorToken;
|
|
859
915
|
if (error) {
|
|
860
916
|
Log === null || Log === void 0 ? void 0 : Log.debug(`error monitor ${characteristic.uuid}, deviceId: ${characteristic.deviceID}: ${error}`);
|
|
@@ -866,28 +922,44 @@ class ReactNativeBleTransport {
|
|
|
866
922
|
Log === null || Log === void 0 ? void 0 : Log.debug('monitor error ignored for stale transport: ', uuid, notifyTransactionId);
|
|
867
923
|
return;
|
|
868
924
|
}
|
|
869
|
-
if (this.
|
|
870
|
-
let
|
|
925
|
+
if (this.getActiveProtocol(uuid) === 'V2') {
|
|
926
|
+
let errorCode = hdShared.HardwareErrorCode.BleCharacteristicNotifyError;
|
|
871
927
|
if ((_a = error.reason) === null || _a === void 0 ? void 0 : _a.includes('The connection has timed out unexpectedly')) {
|
|
872
|
-
|
|
928
|
+
errorCode = hdShared.HardwareErrorCode.BleTimeoutError;
|
|
873
929
|
}
|
|
874
|
-
if ((_b = error.reason) === null || _b === void 0 ? void 0 : _b.includes('Encryption is insufficient')) {
|
|
875
|
-
|
|
930
|
+
else if ((_b = error.reason) === null || _b === void 0 ? void 0 : _b.includes('Encryption is insufficient')) {
|
|
931
|
+
errorCode = hdShared.HardwareErrorCode.BleDeviceBondError;
|
|
876
932
|
}
|
|
877
|
-
if (((_c = error.reason) === null || _c === void 0 ? void 0 : _c.includes('Cannot write client characteristic config descriptor')) ||
|
|
933
|
+
else if (((_c = error.reason) === null || _c === void 0 ? void 0 : _c.includes('Cannot write client characteristic config descriptor')) ||
|
|
878
934
|
((_d = error.reason) === null || _d === void 0 ? void 0 : _d.includes('Cannot find client characteristic config descriptor')) ||
|
|
879
935
|
((_e = error.reason) === null || _e === void 0 ? void 0 : _e.includes('The handle is invalid')) ||
|
|
880
936
|
((_f = error.reason) === null || _f === void 0 ? void 0 : _f.includes('Writing is not permitted')) ||
|
|
881
937
|
((_g = error.reason) === null || _g === void 0 ? void 0 : _g.includes('notify change failed for device'))) {
|
|
938
|
+
errorCode = hdShared.HardwareErrorCode.BleCharacteristicNotifyChangeFailure;
|
|
939
|
+
}
|
|
940
|
+
this.rejectProtocolV2Frames(uuid, hdShared.ERRORS.TypedError(errorCode));
|
|
941
|
+
return;
|
|
942
|
+
}
|
|
943
|
+
if (this.runPromise && this.runPromiseDeviceId === uuid) {
|
|
944
|
+
let ERROR = hdShared.HardwareErrorCode.BleCharacteristicNotifyError;
|
|
945
|
+
if ((_h = error.reason) === null || _h === void 0 ? void 0 : _h.includes('The connection has timed out unexpectedly')) {
|
|
946
|
+
ERROR = hdShared.HardwareErrorCode.BleTimeoutError;
|
|
947
|
+
}
|
|
948
|
+
if ((_j = error.reason) === null || _j === void 0 ? void 0 : _j.includes('Encryption is insufficient')) {
|
|
949
|
+
ERROR = hdShared.HardwareErrorCode.BleDeviceBondError;
|
|
950
|
+
}
|
|
951
|
+
if (((_k = error.reason) === null || _k === void 0 ? void 0 : _k.includes('Cannot write client characteristic config descriptor')) ||
|
|
952
|
+
((_l = error.reason) === null || _l === void 0 ? void 0 : _l.includes('Cannot find client characteristic config descriptor')) ||
|
|
953
|
+
((_m = error.reason) === null || _m === void 0 ? void 0 : _m.includes('The handle is invalid')) ||
|
|
954
|
+
((_o = error.reason) === null || _o === void 0 ? void 0 : _o.includes('Writing is not permitted')) ||
|
|
955
|
+
((_p = error.reason) === null || _p === void 0 ? void 0 : _p.includes('notify change failed for device'))) {
|
|
882
956
|
const notifyError = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleCharacteristicNotifyChangeFailure);
|
|
883
957
|
this.runPromise.reject(notifyError);
|
|
884
|
-
this.rejectAllProtocolV2Frames(notifyError);
|
|
885
958
|
Log === null || Log === void 0 ? void 0 : Log.debug(`${hdShared.HardwareErrorCode.BleCharacteristicNotifyChangeFailure} ${error.message} ${error.reason}`);
|
|
886
959
|
return;
|
|
887
960
|
}
|
|
888
961
|
const notifyError = hdShared.ERRORS.TypedError(ERROR);
|
|
889
962
|
this.runPromise.reject(notifyError);
|
|
890
|
-
this.rejectAllProtocolV2Frames(notifyError);
|
|
891
963
|
Log === null || Log === void 0 ? void 0 : Log.debug(': monitor notify error, and has unreleased Promise', Error);
|
|
892
964
|
}
|
|
893
965
|
return;
|
|
@@ -901,13 +973,13 @@ class ReactNativeBleTransport {
|
|
|
901
973
|
}
|
|
902
974
|
try {
|
|
903
975
|
const data = buffer.Buffer.from(c.value, 'base64');
|
|
904
|
-
const protocol = this.
|
|
976
|
+
const protocol = this.getActiveProtocol(uuid);
|
|
905
977
|
if (!protocol) {
|
|
906
978
|
Log === null || Log === void 0 ? void 0 : Log.debug('monitor data ignored before protocol detection: ', uuid);
|
|
907
979
|
return;
|
|
908
980
|
}
|
|
909
981
|
if (protocol === 'V2') {
|
|
910
|
-
this.handleProtocolV2Notification(uuid, new Uint8Array(data));
|
|
982
|
+
this.handleProtocolV2Notification(uuid, monitorToken, new Uint8Array(data));
|
|
911
983
|
return;
|
|
912
984
|
}
|
|
913
985
|
if (isHeaderChunk(data)) {
|
|
@@ -921,28 +993,40 @@ class ReactNativeBleTransport {
|
|
|
921
993
|
const value = buffer.Buffer.from(buffer$1);
|
|
922
994
|
bufferLength = 0;
|
|
923
995
|
buffer$1 = [];
|
|
924
|
-
(
|
|
996
|
+
if (this.runPromiseDeviceId === uuid) {
|
|
997
|
+
(_q = this.runPromise) === null || _q === void 0 ? void 0 : _q.resolve(value.toString('hex'));
|
|
998
|
+
}
|
|
925
999
|
}
|
|
926
1000
|
}
|
|
927
1001
|
catch (error) {
|
|
928
1002
|
Log === null || Log === void 0 ? void 0 : Log.debug('monitor data error: ', error);
|
|
929
1003
|
const notifyError = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleWriteCharacteristicError);
|
|
930
|
-
(
|
|
931
|
-
|
|
1004
|
+
if (this.getActiveProtocol(uuid) === 'V2') {
|
|
1005
|
+
this.rejectProtocolV2Frames(uuid, notifyError);
|
|
1006
|
+
}
|
|
1007
|
+
else if (this.runPromiseDeviceId === uuid) {
|
|
1008
|
+
(_r = this.runPromise) === null || _r === void 0 ? void 0 : _r.reject(notifyError);
|
|
1009
|
+
}
|
|
932
1010
|
}
|
|
933
1011
|
}, notifyTransactionId);
|
|
934
1012
|
return subscription;
|
|
935
1013
|
}
|
|
936
1014
|
release(uuid, onclose = false) {
|
|
937
|
-
|
|
1015
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1016
|
+
yield this.protocolV2Links.invalidateLink(uuid, 'React Native BLE transport released');
|
|
1017
|
+
return this.releaseNative(uuid, onclose);
|
|
1018
|
+
});
|
|
1019
|
+
}
|
|
1020
|
+
releaseNative(uuid, onclose = false) {
|
|
1021
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
938
1022
|
return __awaiter(this, void 0, void 0, function* () {
|
|
939
1023
|
const transport = transportCache[uuid];
|
|
940
|
-
if (this.runPromise) {
|
|
1024
|
+
if (this.runPromise && this.runPromiseDeviceId === uuid) {
|
|
941
1025
|
const error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleForceCleanRunPromise);
|
|
942
1026
|
this.runPromise.reject(error);
|
|
943
1027
|
this.runPromise = null;
|
|
944
|
-
this.
|
|
945
|
-
this.
|
|
1028
|
+
this.runPromiseDeviceId = null;
|
|
1029
|
+
this.rejectProtocolV2Frames(uuid, error);
|
|
946
1030
|
}
|
|
947
1031
|
else {
|
|
948
1032
|
this.resetProtocolV2Frames(uuid);
|
|
@@ -950,9 +1034,6 @@ class ReactNativeBleTransport {
|
|
|
950
1034
|
if (reactNative.Platform.OS === 'android' && !onclose && transport) {
|
|
951
1035
|
(_a = this.protocolV2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
|
|
952
1036
|
this.resetProtocolV2Frames(uuid);
|
|
953
|
-
if (((_b = this.activeProtocolV2Call) === null || _b === void 0 ? void 0 : _b.uuid) === uuid) {
|
|
954
|
-
this.activeProtocolV2Call = null;
|
|
955
|
-
}
|
|
956
1037
|
return Promise.resolve(true);
|
|
957
1038
|
}
|
|
958
1039
|
if (transport) {
|
|
@@ -960,14 +1041,14 @@ class ReactNativeBleTransport {
|
|
|
960
1041
|
this.monitorTokens.delete(uuid);
|
|
961
1042
|
}
|
|
962
1043
|
Log === null || Log === void 0 ? void 0 : Log.debug('release: removing disconnect subscription for device: ', uuid);
|
|
963
|
-
(
|
|
1044
|
+
(_b = transport.disconnectSubscription) === null || _b === void 0 ? void 0 : _b.remove();
|
|
964
1045
|
transport.disconnectSubscription = undefined;
|
|
965
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('release: removing notify subscription, characteristic: ', (
|
|
966
|
-
(
|
|
1046
|
+
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);
|
|
1047
|
+
(_d = transport.notifySubscription) === null || _d === void 0 ? void 0 : _d.remove();
|
|
967
1048
|
transport.notifySubscription = undefined;
|
|
968
1049
|
if (transport.notifyTransactionId) {
|
|
969
1050
|
try {
|
|
970
|
-
yield ((
|
|
1051
|
+
yield ((_e = this.blePlxManager) === null || _e === void 0 ? void 0 : _e.cancelTransaction(transport.notifyTransactionId));
|
|
971
1052
|
}
|
|
972
1053
|
catch (e) {
|
|
973
1054
|
Log === null || Log === void 0 ? void 0 : Log.debug('release: cancel notify transaction error (ignored): ', (e === null || e === void 0 ? void 0 : e.message) || e);
|
|
@@ -976,12 +1057,12 @@ class ReactNativeBleTransport {
|
|
|
976
1057
|
delete transportCache[uuid];
|
|
977
1058
|
}
|
|
978
1059
|
this.deviceProtocol.delete(uuid);
|
|
979
|
-
this.
|
|
980
|
-
(
|
|
1060
|
+
this.probingProtocols.delete(uuid);
|
|
1061
|
+
(_f = this.protocolV2Assemblers.get(uuid)) === null || _f === void 0 ? void 0 : _f.reset();
|
|
981
1062
|
this.protocolV2Assemblers.delete(uuid);
|
|
982
1063
|
this.resetProtocolV2Frames(uuid);
|
|
983
1064
|
try {
|
|
984
|
-
yield ((
|
|
1065
|
+
yield ((_g = this.blePlxManager) === null || _g === void 0 ? void 0 : _g.cancelTransaction(uuid));
|
|
985
1066
|
}
|
|
986
1067
|
catch (e) {
|
|
987
1068
|
Log === null || Log === void 0 ? void 0 : Log.debug('release: cancel transaction error (ignored): ', (e === null || e === void 0 ? void 0 : e.message) || e);
|
|
@@ -1002,30 +1083,18 @@ class ReactNativeBleTransport {
|
|
|
1002
1083
|
if (this._messages == null) {
|
|
1003
1084
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.TransportNotConfigured);
|
|
1004
1085
|
}
|
|
1005
|
-
const forceRun = name === 'Initialize' || name === 'Cancel';
|
|
1006
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('transport-react-native call this.runPromise', this.runPromise);
|
|
1007
|
-
if (this.runPromise && !forceRun) {
|
|
1008
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.TransportCallInProgress);
|
|
1009
|
-
}
|
|
1010
1086
|
const protocol = this.getProtocolType(uuid);
|
|
1011
1087
|
if (!protocol) {
|
|
1012
1088
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Device protocol has not been detected for ${uuid}`);
|
|
1013
1089
|
}
|
|
1014
|
-
|
|
1015
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('transport-react-native', 'call-', ' name: ', name, ' data: ', {
|
|
1016
|
-
file_name: data === null || data === void 0 ? void 0 : data.file_name,
|
|
1017
|
-
hash: data === null || data === void 0 ? void 0 : data.hash,
|
|
1018
|
-
});
|
|
1019
|
-
}
|
|
1020
|
-
else if (transport.LogBlockCommand.has(name)) {
|
|
1021
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('transport-react-native', 'call-', ' name: ', name, ' protocol: ', protocol);
|
|
1022
|
-
}
|
|
1023
|
-
else {
|
|
1024
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('transport-react-native', 'call-', ' name: ', name, ' data: ', data, ' protocol: ', protocol);
|
|
1025
|
-
}
|
|
1090
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('transport call', transport.createTransportCallLog(name, protocol, data));
|
|
1026
1091
|
if (protocol === 'V2') {
|
|
1027
1092
|
return this.callProtocolV2(uuid, name, data, options);
|
|
1028
1093
|
}
|
|
1094
|
+
const forceRun = name === 'Initialize' || name === 'Cancel';
|
|
1095
|
+
if (this.runPromise && !forceRun) {
|
|
1096
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.TransportCallInProgress);
|
|
1097
|
+
}
|
|
1029
1098
|
return this.callProtocolV1(uuid, name, data, options);
|
|
1030
1099
|
});
|
|
1031
1100
|
}
|
|
@@ -1037,7 +1106,19 @@ class ReactNativeBleTransport {
|
|
|
1037
1106
|
const transport = this.getCachedTransport(uuid);
|
|
1038
1107
|
const runPromise = hdShared.createDeferred();
|
|
1039
1108
|
runPromise.promise.catch(() => undefined);
|
|
1109
|
+
const supersededRunPromise = this.runPromise;
|
|
1110
|
+
if (supersededRunPromise) {
|
|
1111
|
+
supersededRunPromise.reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleForceCleanRunPromise));
|
|
1112
|
+
}
|
|
1040
1113
|
this.runPromise = runPromise;
|
|
1114
|
+
this.runPromiseDeviceId = uuid;
|
|
1115
|
+
const releaseOwnershipIfCurrent = () => {
|
|
1116
|
+
if (this.runPromise === runPromise) {
|
|
1117
|
+
this.runPromise = null;
|
|
1118
|
+
this.runPromiseDeviceId = null;
|
|
1119
|
+
}
|
|
1120
|
+
};
|
|
1121
|
+
const isCurrentOwner = () => this.runPromise === runPromise;
|
|
1041
1122
|
const messages = this._messages;
|
|
1042
1123
|
const buffers = ProtocolV1.encodeTransportPackets(messages, name, data);
|
|
1043
1124
|
let timeout;
|
|
@@ -1058,6 +1139,9 @@ class ReactNativeBleTransport {
|
|
|
1058
1139
|
}
|
|
1059
1140
|
catch (e) {
|
|
1060
1141
|
onError(e);
|
|
1142
|
+
if (isWedgedWriteError(e)) {
|
|
1143
|
+
throw e;
|
|
1144
|
+
}
|
|
1061
1145
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleWriteCharacteristicError);
|
|
1062
1146
|
}
|
|
1063
1147
|
}
|
|
@@ -1085,6 +1169,9 @@ class ReactNativeBleTransport {
|
|
|
1085
1169
|
}
|
|
1086
1170
|
catch (e) {
|
|
1087
1171
|
onError(e);
|
|
1172
|
+
if (isWedgedWriteError(e)) {
|
|
1173
|
+
throw e;
|
|
1174
|
+
}
|
|
1088
1175
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleWriteCharacteristicError);
|
|
1089
1176
|
}
|
|
1090
1177
|
}
|
|
@@ -1095,13 +1182,13 @@ class ReactNativeBleTransport {
|
|
|
1095
1182
|
});
|
|
1096
1183
|
}
|
|
1097
1184
|
if (name === 'EmmcFileWrite') {
|
|
1098
|
-
yield writeChunkedData(buffers, data => transport.writeWithRetry(
|
|
1099
|
-
|
|
1185
|
+
yield writeChunkedData(buffers, data => this.writeBlePacket(uuid, data, payload => transport.writeWithRetry(payload), isCurrentOwner), e => {
|
|
1186
|
+
releaseOwnershipIfCurrent();
|
|
1100
1187
|
Log === null || Log === void 0 ? void 0 : Log.error('writeCharacteristic write error: ', e);
|
|
1101
1188
|
});
|
|
1102
1189
|
}
|
|
1103
1190
|
else if (name === 'FirmwareUpload') {
|
|
1104
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport]
|
|
1191
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Firmware upload transport configured', {
|
|
1105
1192
|
packetCapacity: FIRMWARE_UPLOAD_WRITE_PACKET_CAPACITY,
|
|
1106
1193
|
burstSize: FIRMWARE_UPLOAD_WRITE_BURST_SIZE,
|
|
1107
1194
|
pauseMs: FIRMWARE_UPLOAD_WRITE_PAUSE_MS,
|
|
@@ -1112,7 +1199,7 @@ class ReactNativeBleTransport {
|
|
|
1112
1199
|
let attempt = 0;
|
|
1113
1200
|
while (true) {
|
|
1114
1201
|
try {
|
|
1115
|
-
yield transport.
|
|
1202
|
+
yield this.writeBlePacket(uuid, data, payload => transport.writeWithRetry(payload), isCurrentOwner);
|
|
1116
1203
|
return;
|
|
1117
1204
|
}
|
|
1118
1205
|
catch (error) {
|
|
@@ -1120,36 +1207,18 @@ class ReactNativeBleTransport {
|
|
|
1120
1207
|
if (!retryType || attempt >= FIRMWARE_UPLOAD_WRITE_MAX_RETRIES) {
|
|
1121
1208
|
throw error;
|
|
1122
1209
|
}
|
|
1123
|
-
const
|
|
1124
|
-
const delayMs = shouldReconnect
|
|
1125
|
-
? FIRMWARE_UPLOAD_RECONNECT_RETRY_DELAY_MS
|
|
1126
|
-
: resolveFirmwareUploadRetryDelay(attempt);
|
|
1210
|
+
const delayMs = resolveFirmwareUploadRetryDelay(attempt);
|
|
1127
1211
|
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] FirmwareUpload write retry:', {
|
|
1128
1212
|
attempt: attempt + 1,
|
|
1129
1213
|
delayMs,
|
|
1130
|
-
reconnect: shouldReconnect,
|
|
1131
1214
|
error,
|
|
1132
1215
|
});
|
|
1133
|
-
if (shouldReconnect) {
|
|
1134
|
-
this.firmwareUploadWriteRecoveryIds.add(uuid);
|
|
1135
|
-
}
|
|
1136
1216
|
yield delay(delayMs);
|
|
1137
1217
|
attempt += 1;
|
|
1138
|
-
if (shouldReconnect) {
|
|
1139
|
-
try {
|
|
1140
|
-
yield this.reconnectFirmwareUploadTransport(uuid, transport);
|
|
1141
|
-
}
|
|
1142
|
-
catch (e) {
|
|
1143
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] FirmwareUpload reconnect error:', e);
|
|
1144
|
-
if (attempt >= FIRMWARE_UPLOAD_WRITE_MAX_RETRIES) {
|
|
1145
|
-
throw e;
|
|
1146
|
-
}
|
|
1147
|
-
}
|
|
1148
|
-
}
|
|
1149
1218
|
}
|
|
1150
1219
|
}
|
|
1151
1220
|
}), e => {
|
|
1152
|
-
|
|
1221
|
+
releaseOwnershipIfCurrent();
|
|
1153
1222
|
Log === null || Log === void 0 ? void 0 : Log.error('writeCharacteristic write error: ', e);
|
|
1154
1223
|
});
|
|
1155
1224
|
}
|
|
@@ -1157,11 +1226,17 @@ class ReactNativeBleTransport {
|
|
|
1157
1226
|
for (const o of buffers) {
|
|
1158
1227
|
const outData = o.toString('base64');
|
|
1159
1228
|
try {
|
|
1160
|
-
|
|
1229
|
+
const shouldUseWriteWithResponse = reactNative.Platform.OS === 'ios' && transport.writeCharacteristic.isWritableWithResponse;
|
|
1230
|
+
yield this.writeBlePacket(uuid, outData, payload => shouldUseWriteWithResponse
|
|
1231
|
+
? transport.writeCharacteristic.writeWithResponse(payload)
|
|
1232
|
+
: transport.writeCharacteristic.writeWithoutResponse(payload), isCurrentOwner);
|
|
1161
1233
|
}
|
|
1162
1234
|
catch (e) {
|
|
1163
1235
|
Log === null || Log === void 0 ? void 0 : Log.debug('writeCharacteristic write error: ', e);
|
|
1164
|
-
|
|
1236
|
+
releaseOwnershipIfCurrent();
|
|
1237
|
+
if (isWedgedWriteError(e)) {
|
|
1238
|
+
throw e;
|
|
1239
|
+
}
|
|
1165
1240
|
if (e.errorCode === reactNativeBlePlx.BleErrorCode.DeviceDisconnected) {
|
|
1166
1241
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceNotBonded);
|
|
1167
1242
|
}
|
|
@@ -1190,17 +1265,23 @@ class ReactNativeBleTransport {
|
|
|
1190
1265
|
if (typeof response !== 'string') {
|
|
1191
1266
|
throw new Error('Returning data is not string.');
|
|
1192
1267
|
}
|
|
1193
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('receive data: ', response);
|
|
1194
1268
|
const jsonData = ProtocolV1.decodeMessage(messages, response);
|
|
1195
1269
|
return check.call(jsonData);
|
|
1196
1270
|
}
|
|
1197
1271
|
catch (e) {
|
|
1198
|
-
if (name === '
|
|
1199
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V1
|
|
1272
|
+
if (name === 'GetFeatures' && (options === null || options === void 0 ? void 0 : options.timeoutMs) === PROTOCOL_PROBE_TIMEOUT_MS) {
|
|
1273
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V1 GetFeatures probe call failed:', e);
|
|
1200
1274
|
}
|
|
1201
1275
|
else {
|
|
1202
1276
|
Log === null || Log === void 0 ? void 0 : Log.error('call error: ', e);
|
|
1203
1277
|
}
|
|
1278
|
+
const isProbeTimeout = name === 'GetFeatures' && (options === null || options === void 0 ? void 0 : options.timeoutMs) === PROTOCOL_PROBE_TIMEOUT_MS;
|
|
1279
|
+
const isStaleCall = this.runPromise !== runPromise;
|
|
1280
|
+
if (!isProbeTimeout &&
|
|
1281
|
+
!isStaleCall &&
|
|
1282
|
+
(e === null || e === void 0 ? void 0 : e.errorCode) === hdShared.HardwareErrorCode.BleTimeoutError) {
|
|
1283
|
+
yield this.disconnect(uuid);
|
|
1284
|
+
}
|
|
1204
1285
|
throw e;
|
|
1205
1286
|
}
|
|
1206
1287
|
finally {
|
|
@@ -1208,6 +1289,7 @@ class ReactNativeBleTransport {
|
|
|
1208
1289
|
clearTimeout(timeout);
|
|
1209
1290
|
if (this.runPromise === runPromise) {
|
|
1210
1291
|
this.runPromise = null;
|
|
1292
|
+
this.runPromiseDeviceId = null;
|
|
1211
1293
|
}
|
|
1212
1294
|
}
|
|
1213
1295
|
});
|
|
@@ -1216,10 +1298,11 @@ class ReactNativeBleTransport {
|
|
|
1216
1298
|
this.stopped = true;
|
|
1217
1299
|
}
|
|
1218
1300
|
disconnect(session) {
|
|
1219
|
-
var _a, _b, _c, _d, _e
|
|
1301
|
+
var _a, _b, _c, _d, _e;
|
|
1220
1302
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1221
|
-
|
|
1303
|
+
yield this.protocolV2Links.invalidateLink(session, 'React Native BLE transport disconnected');
|
|
1222
1304
|
const transport = transportCache[session];
|
|
1305
|
+
const monitorToken = (_a = transport === null || transport === void 0 ? void 0 : transport.monitorToken) !== null && _a !== void 0 ? _a : this.monitorTokens.get(session);
|
|
1223
1306
|
if (transport === null || transport === void 0 ? void 0 : transport.disconnectSubscription) {
|
|
1224
1307
|
try {
|
|
1225
1308
|
Log === null || Log === void 0 ? void 0 : Log.debug('disconnect: removing disconnect subscription');
|
|
@@ -1232,7 +1315,7 @@ class ReactNativeBleTransport {
|
|
|
1232
1315
|
}
|
|
1233
1316
|
if (transport === null || transport === void 0 ? void 0 : transport.notifySubscription) {
|
|
1234
1317
|
try {
|
|
1235
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('disconnect: removing notify subscription, characteristic: ', (
|
|
1318
|
+
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);
|
|
1236
1319
|
transport.notifySubscription.remove();
|
|
1237
1320
|
transport.notifySubscription = undefined;
|
|
1238
1321
|
}
|
|
@@ -1242,7 +1325,7 @@ class ReactNativeBleTransport {
|
|
|
1242
1325
|
}
|
|
1243
1326
|
if (session) {
|
|
1244
1327
|
try {
|
|
1245
|
-
yield ((
|
|
1328
|
+
yield ((_c = this.blePlxManager) === null || _c === void 0 ? void 0 : _c.cancelTransaction(session));
|
|
1246
1329
|
}
|
|
1247
1330
|
catch (e) {
|
|
1248
1331
|
Log === null || Log === void 0 ? void 0 : Log.debug('resetSession: cancel transaction error (ignored): ', (e === null || e === void 0 ? void 0 : e.message) || e);
|
|
@@ -1257,7 +1340,7 @@ class ReactNativeBleTransport {
|
|
|
1257
1340
|
}
|
|
1258
1341
|
}
|
|
1259
1342
|
try {
|
|
1260
|
-
yield ((
|
|
1343
|
+
yield ((_d = this.blePlxManager) === null || _d === void 0 ? void 0 : _d.cancelDeviceConnection(session));
|
|
1261
1344
|
}
|
|
1262
1345
|
catch (e) {
|
|
1263
1346
|
Log === null || Log === void 0 ? void 0 : Log.debug('resetSession: manager.cancelDeviceConnection error (ignored): ', (e === null || e === void 0 ? void 0 : e.message) || e);
|
|
@@ -1266,22 +1349,21 @@ class ReactNativeBleTransport {
|
|
|
1266
1349
|
delete transportCache[session];
|
|
1267
1350
|
}
|
|
1268
1351
|
this.deviceProtocol.delete(session);
|
|
1352
|
+
this.probingProtocols.delete(session);
|
|
1269
1353
|
this.deviceProtocolHints.delete(session);
|
|
1354
|
+
this.sessionProtocols.delete(session);
|
|
1355
|
+
this.protocolReprobeFailures.delete(session);
|
|
1270
1356
|
this.protocolV2Assemblers.delete(session);
|
|
1271
1357
|
this.resetProtocolV2Frames(session);
|
|
1272
|
-
if (((_d = this.activeProtocolV2Call) === null || _d === void 0 ? void 0 : _d.uuid) === session) {
|
|
1273
|
-
this.activeProtocolV2Call = null;
|
|
1274
|
-
}
|
|
1275
1358
|
try {
|
|
1276
|
-
(_e =
|
|
1277
|
-
name: (_f = transport === null || transport === void 0 ? void 0 : transport.device) === null || _f === void 0 ? void 0 : _f.name,
|
|
1278
|
-
id: session,
|
|
1279
|
-
connectId: session,
|
|
1280
|
-
});
|
|
1359
|
+
this.emitDeviceDisconnect(session, (_e = transport === null || transport === void 0 ? void 0 : transport.device) === null || _e === void 0 ? void 0 : _e.name, monitorToken);
|
|
1281
1360
|
}
|
|
1282
1361
|
catch (e) {
|
|
1283
1362
|
Log === null || Log === void 0 ? void 0 : Log.error('resetSession: emit disconnect event error: ', e);
|
|
1284
1363
|
}
|
|
1364
|
+
if (monitorToken !== undefined && this.monitorTokens.get(session) === monitorToken) {
|
|
1365
|
+
this.monitorTokens.delete(session);
|
|
1366
|
+
}
|
|
1285
1367
|
yield new Promise(resolve => setTimeout(() => resolve(), 100));
|
|
1286
1368
|
});
|
|
1287
1369
|
}
|
|
@@ -1289,6 +1371,92 @@ class ReactNativeBleTransport {
|
|
|
1289
1371
|
Log === null || Log === void 0 ? void 0 : Log.debug('transport-react-native transport cancel');
|
|
1290
1372
|
if (this.runPromise) ;
|
|
1291
1373
|
this.runPromise = null;
|
|
1374
|
+
this.runPromiseDeviceId = null;
|
|
1375
|
+
}
|
|
1376
|
+
connectWithTimeout(uuid, connect) {
|
|
1377
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1378
|
+
let timer;
|
|
1379
|
+
let timedOut = false;
|
|
1380
|
+
const pending = connect();
|
|
1381
|
+
pending.catch(() => undefined);
|
|
1382
|
+
try {
|
|
1383
|
+
const result = yield Promise.race([
|
|
1384
|
+
pending,
|
|
1385
|
+
new Promise((_, reject) => {
|
|
1386
|
+
timer = setTimeout(() => {
|
|
1387
|
+
timedOut = true;
|
|
1388
|
+
reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleConnectedError, `BLE connect timeout after ${BLE_CONNECT_TIMEOUT_MS}ms for ${uuid}`));
|
|
1389
|
+
}, BLE_CONNECT_TIMEOUT_MS);
|
|
1390
|
+
}),
|
|
1391
|
+
]);
|
|
1392
|
+
return result;
|
|
1393
|
+
}
|
|
1394
|
+
catch (error) {
|
|
1395
|
+
if (timedOut || isNativeOperationTimeoutError(error)) {
|
|
1396
|
+
this.abandonStalledConnection(uuid, timedOut ? 'connect-backstop' : 'connect-native');
|
|
1397
|
+
}
|
|
1398
|
+
throw error;
|
|
1399
|
+
}
|
|
1400
|
+
finally {
|
|
1401
|
+
if (timer)
|
|
1402
|
+
clearTimeout(timer);
|
|
1403
|
+
}
|
|
1404
|
+
});
|
|
1405
|
+
}
|
|
1406
|
+
resolveCharacteristicsWithTimeout(uuid, device) {
|
|
1407
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1408
|
+
let timer;
|
|
1409
|
+
let timedOut = false;
|
|
1410
|
+
const pending = this.resolveCharacteristics(device);
|
|
1411
|
+
pending.catch(() => undefined);
|
|
1412
|
+
try {
|
|
1413
|
+
const result = yield Promise.race([
|
|
1414
|
+
pending,
|
|
1415
|
+
new Promise((_, reject) => {
|
|
1416
|
+
timer = setTimeout(() => {
|
|
1417
|
+
timedOut = true;
|
|
1418
|
+
reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleConnectedError, `BLE GATT setup timeout after ${BLE_GATT_SETUP_TIMEOUT_MS}ms for ${uuid}`));
|
|
1419
|
+
}, BLE_GATT_SETUP_TIMEOUT_MS);
|
|
1420
|
+
}),
|
|
1421
|
+
]);
|
|
1422
|
+
this.connectionSetupTimeoutCounts.delete(uuid);
|
|
1423
|
+
return result;
|
|
1424
|
+
}
|
|
1425
|
+
catch (error) {
|
|
1426
|
+
if (timedOut || isNativeOperationTimeoutError(error)) {
|
|
1427
|
+
this.abandonStalledConnection(uuid, timedOut ? 'gatt-backstop' : 'gatt-native');
|
|
1428
|
+
}
|
|
1429
|
+
throw error;
|
|
1430
|
+
}
|
|
1431
|
+
finally {
|
|
1432
|
+
if (timer)
|
|
1433
|
+
clearTimeout(timer);
|
|
1434
|
+
}
|
|
1435
|
+
});
|
|
1436
|
+
}
|
|
1437
|
+
abandonStalledConnection(uuid, stage) {
|
|
1438
|
+
var _a, _b;
|
|
1439
|
+
const timeouts = ((_a = this.connectionSetupTimeoutCounts.get(uuid)) !== null && _a !== void 0 ? _a : 0) + 1;
|
|
1440
|
+
this.connectionSetupTimeoutCounts.set(uuid, timeouts);
|
|
1441
|
+
Log === null || Log === void 0 ? void 0 : Log.error('[ReactNativeBleTransport] BLE setup timed out:', uuid, {
|
|
1442
|
+
stage,
|
|
1443
|
+
setupTimeoutsSinceSuccess: timeouts,
|
|
1444
|
+
});
|
|
1445
|
+
(_b = this.blePlxManager) === null || _b === void 0 ? void 0 : _b.cancelDeviceConnection(uuid).catch(() => {
|
|
1446
|
+
});
|
|
1447
|
+
const stalled = transportCache[uuid];
|
|
1448
|
+
if (stalled) {
|
|
1449
|
+
delete transportCache[uuid];
|
|
1450
|
+
}
|
|
1451
|
+
this.deviceProtocol.delete(uuid);
|
|
1452
|
+
this.probingProtocols.delete(uuid);
|
|
1453
|
+
this.protocolV2Assemblers.delete(uuid);
|
|
1454
|
+
this.resetProtocolV2Frames(uuid);
|
|
1455
|
+
if (timeouts >= BLE_CONNECT_TIMEOUT_MANAGER_RESET_THRESHOLD) {
|
|
1456
|
+
Log === null || Log === void 0 ? void 0 : Log.error('[ReactNativeBleTransport] BLE setup wedged repeatedly, resetting BLE manager');
|
|
1457
|
+
this.resetPlxManager();
|
|
1458
|
+
this.connectionSetupTimeoutCounts.delete(uuid);
|
|
1459
|
+
}
|
|
1292
1460
|
}
|
|
1293
1461
|
getCachedTransport(uuid) {
|
|
1294
1462
|
const transport = transportCache[uuid];
|
|
@@ -1297,58 +1465,187 @@ class ReactNativeBleTransport {
|
|
|
1297
1465
|
}
|
|
1298
1466
|
return transport;
|
|
1299
1467
|
}
|
|
1468
|
+
writeBlePacket(uuid, data, write, isCurrentOwner) {
|
|
1469
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1470
|
+
let timer;
|
|
1471
|
+
let timedOut = false;
|
|
1472
|
+
try {
|
|
1473
|
+
yield Promise.race([
|
|
1474
|
+
write(data),
|
|
1475
|
+
new Promise((_, reject) => {
|
|
1476
|
+
timer = setTimeout(() => {
|
|
1477
|
+
timedOut = true;
|
|
1478
|
+
reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleWriteCharacteristicError, `BLE write timeout after ${BLE_WRITE_PACKET_TIMEOUT_MS}ms`));
|
|
1479
|
+
}, BLE_WRITE_PACKET_TIMEOUT_MS);
|
|
1480
|
+
}),
|
|
1481
|
+
]);
|
|
1482
|
+
this.writeTimeoutCounts.delete(uuid);
|
|
1483
|
+
}
|
|
1484
|
+
catch (error) {
|
|
1485
|
+
if (timedOut) {
|
|
1486
|
+
if (isCurrentOwner && !isCurrentOwner()) {
|
|
1487
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] stale BLE write timed out, link kept:', uuid);
|
|
1488
|
+
}
|
|
1489
|
+
else {
|
|
1490
|
+
this.tearDownWedgedLink(uuid);
|
|
1491
|
+
}
|
|
1492
|
+
}
|
|
1493
|
+
throw error;
|
|
1494
|
+
}
|
|
1495
|
+
finally {
|
|
1496
|
+
if (timer)
|
|
1497
|
+
clearTimeout(timer);
|
|
1498
|
+
}
|
|
1499
|
+
});
|
|
1500
|
+
}
|
|
1501
|
+
tearDownWedgedLink(uuid) {
|
|
1502
|
+
var _a;
|
|
1503
|
+
const timeouts = ((_a = this.writeTimeoutCounts.get(uuid)) !== null && _a !== void 0 ? _a : 0) + 1;
|
|
1504
|
+
this.writeTimeoutCounts.set(uuid, timeouts);
|
|
1505
|
+
Log === null || Log === void 0 ? void 0 : Log.error('[ReactNativeBleTransport] BLE write timed out, tearing down link:', uuid, {
|
|
1506
|
+
consecutiveWriteTimeouts: timeouts,
|
|
1507
|
+
});
|
|
1508
|
+
const wedged = transportCache[uuid];
|
|
1509
|
+
this.disconnect(uuid).catch(error => {
|
|
1510
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] wedged link teardown failed (ignored):', error);
|
|
1511
|
+
});
|
|
1512
|
+
if (wedged && transportCache[uuid] === wedged) {
|
|
1513
|
+
delete transportCache[uuid];
|
|
1514
|
+
}
|
|
1515
|
+
this.deviceProtocol.delete(uuid);
|
|
1516
|
+
this.probingProtocols.delete(uuid);
|
|
1517
|
+
this.protocolV2Assemblers.delete(uuid);
|
|
1518
|
+
this.resetProtocolV2Frames(uuid);
|
|
1519
|
+
if (timeouts >= BLE_WRITE_TIMEOUT_MANAGER_RESET_THRESHOLD) {
|
|
1520
|
+
Log === null || Log === void 0 ? void 0 : Log.error('[ReactNativeBleTransport] BLE writes wedged repeatedly, resetting BLE manager');
|
|
1521
|
+
this.resetPlxManager();
|
|
1522
|
+
this.writeTimeoutCounts.delete(uuid);
|
|
1523
|
+
}
|
|
1524
|
+
}
|
|
1525
|
+
resetPlxManager() {
|
|
1526
|
+
const manager = this.blePlxManager;
|
|
1527
|
+
this.blePlxManager = undefined;
|
|
1528
|
+
Object.keys(transportCache).forEach(key => {
|
|
1529
|
+
delete transportCache[key];
|
|
1530
|
+
});
|
|
1531
|
+
this.deviceProtocol.clear();
|
|
1532
|
+
this.probingProtocols.clear();
|
|
1533
|
+
this.sessionProtocols.clear();
|
|
1534
|
+
this.protocolReprobeFailures.clear();
|
|
1535
|
+
this.monitorTokens.clear();
|
|
1536
|
+
this.protocolV2Assemblers.clear();
|
|
1537
|
+
try {
|
|
1538
|
+
manager === null || manager === void 0 ? void 0 : manager.destroy();
|
|
1539
|
+
}
|
|
1540
|
+
catch (error) {
|
|
1541
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] BLE manager destroy failed (ignored):', error);
|
|
1542
|
+
}
|
|
1543
|
+
}
|
|
1300
1544
|
createProtocolMismatchError(expected) {
|
|
1301
1545
|
return hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Device protocol mismatch: expected ${expected}, but device did not respond to expected protocol`);
|
|
1302
1546
|
}
|
|
1303
1547
|
createProtocolDetectionError() {
|
|
1304
|
-
return hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleTimeoutError, 'Unable to detect BLE protocol: device did not respond to Protocol V1
|
|
1548
|
+
return hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleTimeoutError, 'Unable to detect BLE protocol: device did not respond to Protocol V1 GetFeatures or Protocol V2 Ping');
|
|
1305
1549
|
}
|
|
1306
1550
|
clearProbeProtocol(uuid, protocol) {
|
|
1551
|
+
if (this.probingProtocols.get(uuid) === protocol) {
|
|
1552
|
+
this.probingProtocols.delete(uuid);
|
|
1553
|
+
}
|
|
1307
1554
|
if (this.deviceProtocol.get(uuid) === protocol) {
|
|
1308
1555
|
this.deviceProtocol.delete(uuid);
|
|
1309
1556
|
}
|
|
1310
1557
|
}
|
|
1311
|
-
|
|
1558
|
+
getActiveProtocol(uuid) {
|
|
1559
|
+
var _a;
|
|
1560
|
+
return (_a = this.deviceProtocol.get(uuid)) !== null && _a !== void 0 ? _a : this.probingProtocols.get(uuid);
|
|
1561
|
+
}
|
|
1562
|
+
detectProtocol(uuid, expectedProtocol, protocolHint, rebuildTransport) {
|
|
1563
|
+
var _a;
|
|
1312
1564
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1565
|
+
if (reactNative.Platform.OS === 'ios' && expectedProtocol) {
|
|
1566
|
+
this.deviceProtocol.set(uuid, expectedProtocol);
|
|
1567
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] protocol selected', {
|
|
1568
|
+
deviceId: uuid,
|
|
1569
|
+
protocol: expectedProtocol,
|
|
1570
|
+
source: 'expected',
|
|
1571
|
+
});
|
|
1572
|
+
return expectedProtocol;
|
|
1573
|
+
}
|
|
1313
1574
|
if (expectedProtocol === 'V1') {
|
|
1314
1575
|
if (yield this.probeProtocolV1(uuid)) {
|
|
1315
1576
|
this.deviceProtocol.set(uuid, 'V1');
|
|
1316
|
-
|
|
1577
|
+
this.sessionProtocols.set(uuid, 'V1');
|
|
1578
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] protocol detected', {
|
|
1579
|
+
deviceId: uuid,
|
|
1580
|
+
protocol: 'V1',
|
|
1581
|
+
source: 'expected',
|
|
1582
|
+
});
|
|
1317
1583
|
return 'V1';
|
|
1318
1584
|
}
|
|
1319
1585
|
throw this.createProtocolMismatchError(expectedProtocol);
|
|
1320
1586
|
}
|
|
1321
1587
|
if (expectedProtocol === 'V2') {
|
|
1322
|
-
this.
|
|
1323
|
-
|
|
1324
|
-
|
|
1588
|
+
if (yield this.probeProtocolV2(uuid)) {
|
|
1589
|
+
this.deviceProtocol.set(uuid, 'V2');
|
|
1590
|
+
this.sessionProtocols.set(uuid, 'V2');
|
|
1591
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] protocol detected', {
|
|
1592
|
+
deviceId: uuid,
|
|
1593
|
+
protocol: 'V2',
|
|
1594
|
+
source: 'expected',
|
|
1595
|
+
});
|
|
1596
|
+
return 'V2';
|
|
1597
|
+
}
|
|
1598
|
+
throw this.createProtocolMismatchError(expectedProtocol);
|
|
1325
1599
|
}
|
|
1326
|
-
const
|
|
1600
|
+
const sessionProtocol = this.sessionProtocols.get(uuid);
|
|
1601
|
+
const reprobeFailures = (_a = this.protocolReprobeFailures.get(uuid)) !== null && _a !== void 0 ? _a : 0;
|
|
1602
|
+
const fullProbeOrder = protocolHint === 'V2' || this.deviceProtocol.get(uuid) === 'V2' ? ['V2', 'V1'] : ['V1', 'V2'];
|
|
1603
|
+
const trustSessionProtocol = sessionProtocol !== undefined &&
|
|
1604
|
+
!protocolHint &&
|
|
1605
|
+
reprobeFailures < PROTOCOL_REPROBE_FALLBACK_ATTEMPTS;
|
|
1606
|
+
const probeOrder = trustSessionProtocol ? [sessionProtocol] : fullProbeOrder;
|
|
1327
1607
|
for (let i = 0; i < probeOrder.length; i += 1) {
|
|
1328
1608
|
const protocol = probeOrder[i];
|
|
1329
1609
|
if (i > 0) {
|
|
1330
1610
|
yield this.resetProbeStateAfterProtocolProbe(uuid, probeOrder[i - 1]);
|
|
1611
|
+
if (!transportCache[uuid]) {
|
|
1612
|
+
if (!rebuildTransport) {
|
|
1613
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.TransportNotFound);
|
|
1614
|
+
}
|
|
1615
|
+
yield rebuildTransport();
|
|
1616
|
+
}
|
|
1331
1617
|
}
|
|
1332
1618
|
const detected = protocol === 'V1' ? yield this.probeProtocolV1(uuid) : yield this.probeProtocolV2(uuid);
|
|
1333
1619
|
if (detected) {
|
|
1334
1620
|
this.deviceProtocol.set(uuid, protocol);
|
|
1335
|
-
|
|
1621
|
+
this.sessionProtocols.set(uuid, protocol);
|
|
1622
|
+
this.protocolReprobeFailures.delete(uuid);
|
|
1623
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] protocol detected', {
|
|
1624
|
+
deviceId: uuid,
|
|
1625
|
+
protocol,
|
|
1626
|
+
source: 'probe',
|
|
1627
|
+
});
|
|
1336
1628
|
return protocol;
|
|
1337
1629
|
}
|
|
1338
1630
|
}
|
|
1631
|
+
if (trustSessionProtocol) {
|
|
1632
|
+
this.protocolReprobeFailures.set(uuid, reprobeFailures + 1);
|
|
1633
|
+
}
|
|
1634
|
+
else {
|
|
1635
|
+
this.protocolReprobeFailures.delete(uuid);
|
|
1636
|
+
}
|
|
1339
1637
|
this.deviceProtocol.delete(uuid);
|
|
1638
|
+
this.probingProtocols.delete(uuid);
|
|
1340
1639
|
throw this.createProtocolDetectionError();
|
|
1341
1640
|
});
|
|
1342
1641
|
}
|
|
1343
1642
|
resetProbeStateAfterProtocolProbe(uuid, protocol) {
|
|
1344
|
-
var _a, _b, _c
|
|
1643
|
+
var _a, _b, _c;
|
|
1345
1644
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1346
1645
|
const transport = transportCache[uuid];
|
|
1646
|
+
yield this.protocolV2Links.invalidateLink(uuid, `Reset notify state after Protocol ${protocol} probe`);
|
|
1347
1647
|
(_a = this.protocolV2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
|
|
1348
1648
|
this.resetProtocolV2Frames(uuid);
|
|
1349
|
-
if (((_b = this.activeProtocolV2Call) === null || _b === void 0 ? void 0 : _b.uuid) === uuid) {
|
|
1350
|
-
this.activeProtocolV2Call = null;
|
|
1351
|
-
}
|
|
1352
1649
|
if (this.runPromise) {
|
|
1353
1650
|
const error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleForceCleanRunPromise);
|
|
1354
1651
|
this.runPromise.reject(error);
|
|
@@ -1360,11 +1657,11 @@ class ReactNativeBleTransport {
|
|
|
1360
1657
|
if (this.monitorTokens.get(uuid) === transport.monitorToken) {
|
|
1361
1658
|
this.monitorTokens.delete(uuid);
|
|
1362
1659
|
}
|
|
1363
|
-
(
|
|
1660
|
+
(_b = transport.notifySubscription) === null || _b === void 0 ? void 0 : _b.remove();
|
|
1364
1661
|
transport.notifySubscription = undefined;
|
|
1365
1662
|
if (previousNotifyTransactionId) {
|
|
1366
1663
|
try {
|
|
1367
|
-
yield ((
|
|
1664
|
+
yield ((_c = this.blePlxManager) === null || _c === void 0 ? void 0 : _c.cancelTransaction(previousNotifyTransactionId));
|
|
1368
1665
|
}
|
|
1369
1666
|
catch (error) {
|
|
1370
1667
|
Log === null || Log === void 0 ? void 0 : Log.debug(`[ReactNativeBleTransport] cancel notify after Protocol ${protocol} probe failed:`, (error === null || error === void 0 ? void 0 : error.message) || error);
|
|
@@ -1390,13 +1687,17 @@ class ReactNativeBleTransport {
|
|
|
1390
1687
|
return false;
|
|
1391
1688
|
}
|
|
1392
1689
|
try {
|
|
1393
|
-
this.
|
|
1394
|
-
yield this.callProtocolV1(uuid, '
|
|
1690
|
+
this.probingProtocols.set(uuid, 'V1');
|
|
1691
|
+
yield this.callProtocolV1(uuid, 'GetFeatures', {}, { timeoutMs: PROTOCOL_PROBE_TIMEOUT_MS });
|
|
1692
|
+
this.probingProtocols.delete(uuid);
|
|
1395
1693
|
return true;
|
|
1396
1694
|
}
|
|
1397
1695
|
catch (error) {
|
|
1398
1696
|
this.clearProbeProtocol(uuid, 'V1');
|
|
1399
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V1
|
|
1697
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V1 GetFeatures probe failed:', error);
|
|
1698
|
+
if (isWedgedWriteError(error)) {
|
|
1699
|
+
throw error;
|
|
1700
|
+
}
|
|
1400
1701
|
return false;
|
|
1401
1702
|
}
|
|
1402
1703
|
});
|
|
@@ -1407,7 +1708,7 @@ class ReactNativeBleTransport {
|
|
|
1407
1708
|
if (!this._messages || !this._messagesV2) {
|
|
1408
1709
|
return false;
|
|
1409
1710
|
}
|
|
1410
|
-
this.
|
|
1711
|
+
this.probingProtocols.set(uuid, 'V2');
|
|
1411
1712
|
(_a = this.protocolV2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
|
|
1412
1713
|
const detected = yield transport.probeProtocolV2({
|
|
1413
1714
|
call: (name, data, options) => this.callProtocolV2(uuid, name, data, options),
|
|
@@ -1423,17 +1724,16 @@ class ReactNativeBleTransport {
|
|
|
1423
1724
|
if (!detected) {
|
|
1424
1725
|
this.clearProbeProtocol(uuid, 'V2');
|
|
1425
1726
|
}
|
|
1727
|
+
else {
|
|
1728
|
+
this.probingProtocols.delete(uuid);
|
|
1729
|
+
}
|
|
1426
1730
|
return detected;
|
|
1427
1731
|
});
|
|
1428
1732
|
}
|
|
1429
|
-
handleProtocolV2Notification(uuid, data) {
|
|
1430
|
-
var _a, _b, _c;
|
|
1733
|
+
handleProtocolV2Notification(uuid, monitorToken, data) {
|
|
1431
1734
|
try {
|
|
1432
|
-
if (
|
|
1433
|
-
(_b = this.protocolV2Assemblers.get(uuid)) === null || _b === void 0 ? void 0 : _b.reset();
|
|
1434
|
-
this.resetProtocolV2Frames(uuid);
|
|
1735
|
+
if (this.monitorTokens.get(uuid) !== monitorToken)
|
|
1435
1736
|
return;
|
|
1436
|
-
}
|
|
1437
1737
|
if (data.length === 0)
|
|
1438
1738
|
return;
|
|
1439
1739
|
const assembler = this.protocolV2Assemblers.get(uuid);
|
|
@@ -1446,8 +1746,10 @@ class ReactNativeBleTransport {
|
|
|
1446
1746
|
catch (error) {
|
|
1447
1747
|
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V2 notification error:', error);
|
|
1448
1748
|
const notifyError = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleWriteCharacteristicError);
|
|
1449
|
-
|
|
1450
|
-
this.
|
|
1749
|
+
this.rejectProtocolV2Frames(uuid, notifyError);
|
|
1750
|
+
this.protocolV2Links
|
|
1751
|
+
.invalidateLink(uuid, `Protocol V2 notification error: ${error}`)
|
|
1752
|
+
.catch(invalidateError => Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V2 notify cleanup failed:', invalidateError));
|
|
1451
1753
|
}
|
|
1452
1754
|
}
|
|
1453
1755
|
getProtocolV2FrameQueue(uuid) {
|
|
@@ -1467,20 +1769,16 @@ class ReactNativeBleTransport {
|
|
|
1467
1769
|
}
|
|
1468
1770
|
this.getProtocolV2FrameQueue(uuid).push(frame);
|
|
1469
1771
|
}
|
|
1470
|
-
rejectAllProtocolV2Frames(error) {
|
|
1471
|
-
this.protocolV2FrameQueues.clear();
|
|
1472
|
-
for (const framePromise of this.protocolV2FramePromises.values()) {
|
|
1473
|
-
framePromise.reject(error);
|
|
1474
|
-
}
|
|
1475
|
-
this.protocolV2FramePromises.clear();
|
|
1476
|
-
}
|
|
1477
1772
|
resetProtocolV2Frames(uuid) {
|
|
1478
|
-
this.
|
|
1479
|
-
this.protocolV2FramePromises.delete(uuid);
|
|
1773
|
+
this.rejectProtocolV2Frames(uuid, new Error(`Protocol V2 frame state reset for ${uuid}`));
|
|
1480
1774
|
}
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1775
|
+
rejectProtocolV2Frames(uuid, error) {
|
|
1776
|
+
this.protocolV2FrameQueues.delete(uuid);
|
|
1777
|
+
const framePromise = this.protocolV2FramePromises.get(uuid);
|
|
1778
|
+
if (framePromise) {
|
|
1779
|
+
this.protocolV2FramePromises.delete(uuid);
|
|
1780
|
+
framePromise.reject(error);
|
|
1781
|
+
}
|
|
1484
1782
|
}
|
|
1485
1783
|
readProtocolV2Frame(uuid) {
|
|
1486
1784
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -1500,133 +1798,153 @@ class ReactNativeBleTransport {
|
|
|
1500
1798
|
}
|
|
1501
1799
|
});
|
|
1502
1800
|
}
|
|
1503
|
-
|
|
1801
|
+
writeProtocolV2Packet(uuid, transport, base64, context, assertCurrentGeneration) {
|
|
1802
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1803
|
+
const shouldUseWriteWithResponse = transport.writeCharacteristic.isWritableWithResponse &&
|
|
1804
|
+
(context.writeWithResponse === true || (reactNative.Platform.OS === 'ios' && !context.highVolume));
|
|
1805
|
+
let attempt = 0;
|
|
1806
|
+
for (;;) {
|
|
1807
|
+
assertCurrentGeneration();
|
|
1808
|
+
if (context.signal.aborted) {
|
|
1809
|
+
throw new Error(`Protocol V2 BLE write aborted for ${context.messageName}`);
|
|
1810
|
+
}
|
|
1811
|
+
try {
|
|
1812
|
+
yield this.writeBlePacket(uuid, base64, payload => shouldUseWriteWithResponse
|
|
1813
|
+
? transport.writeCharacteristic.writeWithResponse(payload)
|
|
1814
|
+
: transport.writeCharacteristic.writeWithoutResponse(payload), () => {
|
|
1815
|
+
try {
|
|
1816
|
+
assertCurrentGeneration();
|
|
1817
|
+
return !context.signal.aborted;
|
|
1818
|
+
}
|
|
1819
|
+
catch (_a) {
|
|
1820
|
+
return false;
|
|
1821
|
+
}
|
|
1822
|
+
});
|
|
1823
|
+
assertCurrentGeneration();
|
|
1824
|
+
return;
|
|
1825
|
+
}
|
|
1826
|
+
catch (error) {
|
|
1827
|
+
if (getFirmwareUploadWriteRetryType(error) !== 'congested' ||
|
|
1828
|
+
attempt >= FIRMWARE_UPLOAD_WRITE_MAX_RETRIES) {
|
|
1829
|
+
throw error;
|
|
1830
|
+
}
|
|
1831
|
+
const delayMs = resolveFirmwareUploadRetryDelay(attempt);
|
|
1832
|
+
attempt += 1;
|
|
1833
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V2 congested write retry:', {
|
|
1834
|
+
name: context.messageName,
|
|
1835
|
+
attempt,
|
|
1836
|
+
delayMs,
|
|
1837
|
+
});
|
|
1838
|
+
yield delay(delayMs);
|
|
1839
|
+
}
|
|
1840
|
+
}
|
|
1841
|
+
});
|
|
1842
|
+
}
|
|
1843
|
+
writeProtocolV2Frame(uuid, transport$1, frame, context, assertCurrentGeneration) {
|
|
1504
1844
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1505
1845
|
const tuning = getProtocolV2BleTuning();
|
|
1506
1846
|
const packetCapacity = resolveProtocolV2PacketCapacity({
|
|
1507
1847
|
platform: reactNative.Platform.OS,
|
|
1508
1848
|
iosPacketLength: tuning.iosPacketLength,
|
|
1509
1849
|
androidPacketLength: tuning.androidPacketLength,
|
|
1510
|
-
mtu: reactNative.Platform.OS === 'android' ? transport.mtuSize : undefined,
|
|
1850
|
+
mtu: reactNative.Platform.OS === 'android' ? transport$1.mtuSize : undefined,
|
|
1851
|
+
});
|
|
1852
|
+
const initialDelayMs = reactNative.Platform.OS === 'ios' && !context.highVolume && frame.length <= packetCapacity
|
|
1853
|
+
? IOS_PROTOCOL_V2_CONTROL_WRITE_DELAY_MS
|
|
1854
|
+
: 0;
|
|
1855
|
+
yield transport.writeProtocolV2BleFrame({
|
|
1856
|
+
frame,
|
|
1857
|
+
packetCapacity,
|
|
1858
|
+
assertActive: assertCurrentGeneration,
|
|
1859
|
+
signal: context.signal,
|
|
1860
|
+
abortMessage: `Protocol V2 BLE write aborted for ${context.messageName}`,
|
|
1861
|
+
initialDelayMs,
|
|
1862
|
+
burstSize: FIRMWARE_UPLOAD_WRITE_BURST_SIZE,
|
|
1863
|
+
burstPauseMs: FIRMWARE_UPLOAD_WRITE_PAUSE_MS,
|
|
1864
|
+
flushDelayMs: FIRMWARE_UPLOAD_WRITE_FLUSH_DELAY_MS,
|
|
1865
|
+
wait: delay,
|
|
1866
|
+
writePacket: packet => this.writeProtocolV2Packet(uuid, transport$1, buffer.Buffer.from(packet).toString('base64'), context, assertCurrentGeneration),
|
|
1511
1867
|
});
|
|
1512
|
-
const writeWithResponse = !!(options === null || options === void 0 ? void 0 : options.writeWithResponse) || (!!(options === null || options === void 0 ? void 0 : options.highVolume) && tuning.highVolumeWriteWithResponse);
|
|
1513
|
-
const writeMode = resolveBleWriteMode(transport.writeCharacteristic, writeWithResponse ? 'withResponse' : 'withoutResponse');
|
|
1514
|
-
const shouldThrottle = !!(options === null || options === void 0 ? void 0 : options.highVolume) && writeMode === 'withoutResponse';
|
|
1515
|
-
let packetsWritten = 0;
|
|
1516
|
-
for (let offset = 0; offset < frame.length; offset += packetCapacity) {
|
|
1517
|
-
const chunk = frame.slice(offset, offset + packetCapacity);
|
|
1518
|
-
const base64 = buffer.Buffer.from(chunk).toString('base64');
|
|
1519
|
-
if (writeMode === 'withResponse') {
|
|
1520
|
-
yield transport.writeCharacteristic.writeWithResponse(base64);
|
|
1521
|
-
}
|
|
1522
|
-
else {
|
|
1523
|
-
yield transport.writeCharacteristic.writeWithoutResponse(base64);
|
|
1524
|
-
}
|
|
1525
|
-
packetsWritten += 1;
|
|
1526
|
-
if (shouldThrottle &&
|
|
1527
|
-
packetsWritten % tuning.highVolumeWriteBurstSize === 0 &&
|
|
1528
|
-
offset + packetCapacity < frame.length) {
|
|
1529
|
-
yield delay(tuning.highVolumeWritePauseMs);
|
|
1530
|
-
}
|
|
1531
|
-
}
|
|
1532
|
-
if (shouldThrottle) {
|
|
1533
|
-
yield delay(tuning.highVolumeWriteFlushDelayMs);
|
|
1534
|
-
}
|
|
1535
1868
|
});
|
|
1536
1869
|
}
|
|
1537
1870
|
callProtocolV2(uuid, name, data, options) {
|
|
1538
|
-
var _a, _b, _c, _d;
|
|
1539
1871
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1540
1872
|
if (!this._messages || !this._messagesV2) {
|
|
1541
1873
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.TransportNotConfigured);
|
|
1542
1874
|
}
|
|
1543
|
-
const
|
|
1544
|
-
if (this.runPromise) {
|
|
1545
|
-
if (!forceRun) {
|
|
1546
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.TransportCallInProgress);
|
|
1547
|
-
}
|
|
1548
|
-
const error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleForceCleanRunPromise);
|
|
1549
|
-
this.runPromise.reject(error);
|
|
1550
|
-
this.rejectAllProtocolV2Frames(error);
|
|
1551
|
-
this.runPromise = null;
|
|
1552
|
-
this.activeProtocolV2Call = null;
|
|
1553
|
-
}
|
|
1554
|
-
const transport$1 = this.getCachedTransport(uuid);
|
|
1555
|
-
const runPromise = hdShared.createDeferred();
|
|
1556
|
-
runPromise.promise.catch(() => undefined);
|
|
1557
|
-
this.runPromise = runPromise;
|
|
1558
|
-
const callToken = this.nextProtocolV2CallToken++;
|
|
1559
|
-
this.activeProtocolV2Call = { uuid, token: callToken };
|
|
1560
|
-
(_a = this.protocolV2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
|
|
1561
|
-
this.resetProtocolV2Frames(uuid);
|
|
1562
|
-
let completed = false;
|
|
1563
|
-
const callOptions = Object.assign(Object.assign({}, options), { timeoutMs: (_b = options === null || options === void 0 ? void 0 : options.timeoutMs) !== null && _b !== void 0 ? _b : BLE_RESPONSE_TIMEOUT_MS });
|
|
1875
|
+
const callOptions = options;
|
|
1564
1876
|
const highVolumeWrite = transport.LogBlockCommand.has(name);
|
|
1565
1877
|
if (highVolumeWrite) {
|
|
1566
1878
|
const tuning = getProtocolV2BleTuning();
|
|
1567
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V2 high-volume write
|
|
1879
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V2 high-volume write configured', {
|
|
1880
|
+
name,
|
|
1881
|
+
writeMode: (options === null || options === void 0 ? void 0 : options.writeWithResponse) ? 'withResponse' : 'withoutResponse',
|
|
1568
1882
|
packetCapacity: reactNative.Platform.OS === 'ios' ? tuning.iosPacketLength : tuning.androidPacketLength,
|
|
1569
|
-
burstSize: tuning.highVolumeWriteBurstSize,
|
|
1570
|
-
pauseMs: tuning.highVolumeWritePauseMs,
|
|
1571
|
-
flushDelayMs: tuning.highVolumeWriteFlushDelayMs,
|
|
1572
|
-
writeWithResponse: tuning.highVolumeWriteWithResponse,
|
|
1573
1883
|
});
|
|
1574
1884
|
}
|
|
1575
1885
|
try {
|
|
1576
|
-
|
|
1577
|
-
schemas: {
|
|
1578
|
-
protocolV1: this._messages,
|
|
1579
|
-
protocolV2: this._messagesV2,
|
|
1580
|
-
},
|
|
1581
|
-
router: transport.PROTOCOL_V2_CHANNEL_BLE_UART,
|
|
1582
|
-
writeFrame: (frame) => __awaiter(this, void 0, void 0, function* () {
|
|
1583
|
-
yield this.writeProtocolV2Frame(transport$1, frame, {
|
|
1584
|
-
highVolume: highVolumeWrite,
|
|
1585
|
-
});
|
|
1586
|
-
}),
|
|
1587
|
-
readFrame: () => __awaiter(this, void 0, void 0, function* () {
|
|
1588
|
-
const rxFrame = yield this.readProtocolV2Frame(uuid);
|
|
1589
|
-
if (!(rxFrame instanceof Uint8Array)) {
|
|
1590
|
-
throw new Error('Protocol V2 response is not Uint8Array');
|
|
1591
|
-
}
|
|
1592
|
-
return rxFrame;
|
|
1593
|
-
}),
|
|
1594
|
-
logger: Log,
|
|
1595
|
-
logPrefix: 'ProtocolV2 RN-BLE',
|
|
1596
|
-
createTimeoutError: (_messageName, timeout) => hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleTimeoutError, `BLE response timeout after ${timeout}ms for ${name}`),
|
|
1597
|
-
});
|
|
1598
|
-
const result = yield session.call(name, data, callOptions);
|
|
1599
|
-
completed = true;
|
|
1600
|
-
return result;
|
|
1886
|
+
return yield this.protocolV2Links.call(uuid, () => this.createProtocolV2Adapter(uuid), name, data, callOptions);
|
|
1601
1887
|
}
|
|
1602
1888
|
catch (e) {
|
|
1603
|
-
if (this.isActiveProtocolV2Call(uuid, callToken)) {
|
|
1604
|
-
(_c = this.protocolV2Assemblers.get(uuid)) === null || _c === void 0 ? void 0 : _c.reset();
|
|
1605
|
-
this.resetProtocolV2Frames(uuid);
|
|
1606
|
-
}
|
|
1607
1889
|
Log === null || Log === void 0 ? void 0 : Log.error('[ReactNativeBleTransport] Protocol V2 call error:', e);
|
|
1608
1890
|
throw e;
|
|
1609
1891
|
}
|
|
1610
|
-
finally {
|
|
1611
|
-
if (this.isActiveProtocolV2Call(uuid, callToken)) {
|
|
1612
|
-
if (!completed) {
|
|
1613
|
-
(_d = this.protocolV2Assemblers.get(uuid)) === null || _d === void 0 ? void 0 : _d.reset();
|
|
1614
|
-
}
|
|
1615
|
-
this.resetProtocolV2Frames(uuid);
|
|
1616
|
-
this.activeProtocolV2Call = null;
|
|
1617
|
-
}
|
|
1618
|
-
if (this.runPromise === runPromise) {
|
|
1619
|
-
this.runPromise = null;
|
|
1620
|
-
}
|
|
1621
|
-
}
|
|
1622
1892
|
});
|
|
1623
1893
|
}
|
|
1894
|
+
createProtocolV2Adapter(uuid) {
|
|
1895
|
+
var _a;
|
|
1896
|
+
const generation = (_a = this.monitorTokens.get(uuid)) !== null && _a !== void 0 ? _a : 0;
|
|
1897
|
+
const assertCurrentGeneration = () => {
|
|
1898
|
+
if (this.monitorTokens.get(uuid) !== generation) {
|
|
1899
|
+
throw new Error(`Protocol V2 monitor generation changed for ${uuid}`);
|
|
1900
|
+
}
|
|
1901
|
+
};
|
|
1902
|
+
return {
|
|
1903
|
+
router: transport.PROTOCOL_V2_CHANNEL_BLE_UART,
|
|
1904
|
+
maxFrameBytes: transport.PROTOCOL_V2_BLE_FRAME_MAX_BYTES,
|
|
1905
|
+
generation,
|
|
1906
|
+
prepareCall: () => {
|
|
1907
|
+
var _a;
|
|
1908
|
+
assertCurrentGeneration();
|
|
1909
|
+
(_a = this.protocolV2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
|
|
1910
|
+
this.resetProtocolV2Frames(uuid);
|
|
1911
|
+
},
|
|
1912
|
+
writeFrame: (frame, context) => __awaiter(this, void 0, void 0, function* () {
|
|
1913
|
+
assertCurrentGeneration();
|
|
1914
|
+
const currentTransport = this.getCachedTransport(uuid);
|
|
1915
|
+
yield this.writeProtocolV2Frame(uuid, currentTransport, frame, context, assertCurrentGeneration);
|
|
1916
|
+
}),
|
|
1917
|
+
readFrame: () => __awaiter(this, void 0, void 0, function* () {
|
|
1918
|
+
assertCurrentGeneration();
|
|
1919
|
+
const rxFrame = yield this.readProtocolV2Frame(uuid);
|
|
1920
|
+
if (!(rxFrame instanceof Uint8Array)) {
|
|
1921
|
+
throw new Error('Protocol V2 response is not Uint8Array');
|
|
1922
|
+
}
|
|
1923
|
+
return rxFrame;
|
|
1924
|
+
}),
|
|
1925
|
+
reset: (reason) => {
|
|
1926
|
+
var _a;
|
|
1927
|
+
(_a = this.protocolV2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
|
|
1928
|
+
this.rejectProtocolV2Frames(uuid, new Error(reason));
|
|
1929
|
+
},
|
|
1930
|
+
logger: Log,
|
|
1931
|
+
logPrefix: 'ProtocolV2 RN-BLE',
|
|
1932
|
+
createTimeoutError: (messageName, timeout) => hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleTimeoutError, `BLE response timeout after ${timeout}ms for ${messageName}`),
|
|
1933
|
+
};
|
|
1934
|
+
}
|
|
1624
1935
|
getProtocolType(path) {
|
|
1625
|
-
return this.
|
|
1936
|
+
return this.getActiveProtocol(path);
|
|
1626
1937
|
}
|
|
1627
1938
|
}
|
|
1628
1939
|
|
|
1940
|
+
exports.BLE_CONNECT_TIMEOUT_MANAGER_RESET_THRESHOLD = BLE_CONNECT_TIMEOUT_MANAGER_RESET_THRESHOLD;
|
|
1941
|
+
exports.BLE_CONNECT_TIMEOUT_MS = BLE_CONNECT_TIMEOUT_MS;
|
|
1942
|
+
exports.BLE_GATT_SETUP_TIMEOUT_MS = BLE_GATT_SETUP_TIMEOUT_MS;
|
|
1943
|
+
exports.BLE_WRITE_PACKET_TIMEOUT_MS = BLE_WRITE_PACKET_TIMEOUT_MS;
|
|
1944
|
+
exports.BLE_WRITE_TIMEOUT_MANAGER_RESET_THRESHOLD = BLE_WRITE_TIMEOUT_MANAGER_RESET_THRESHOLD;
|
|
1945
|
+
exports.PROTOCOL_REPROBE_FALLBACK_ATTEMPTS = PROTOCOL_REPROBE_FALLBACK_ATTEMPTS;
|
|
1629
1946
|
exports.configureProtocolV2BleTuning = configureProtocolV2BleTuning;
|
|
1630
1947
|
exports["default"] = ReactNativeBleTransport;
|
|
1948
|
+
exports.getFirmwareUploadWriteRetryType = getFirmwareUploadWriteRetryType;
|
|
1631
1949
|
exports.getProtocolV2BleTuning = getProtocolV2BleTuning;
|
|
1632
1950
|
exports.resetProtocolV2BleTuning = resetProtocolV2BleTuning;
|