@onekeyfe/hd-transport-react-native 1.2.0-alpha.3 → 1.2.0-alpha.30
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/bleStrategy.d.ts +0 -2
- package/dist/bleStrategy.d.ts.map +1 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/index.d.ts +19 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +282 -254
- package/dist/subscribeBleOn.d.ts.map +1 -1
- package/dist/transportLog.d.ts +13 -0
- package/dist/transportLog.d.ts.map +1 -0
- package/jest.config.js +5 -0
- package/package.json +7 -6
- package/src/__tests__/bleStrategy.test.ts +1 -6
- package/src/__tests__/protocolV2Link.test.ts +342 -0
- package/src/bleStrategy.ts +0 -25
- package/src/constants.ts +9 -1
- package/src/index.ts +294 -283
- package/src/subscribeBleOn.ts +0 -2
- package/src/transportLog.ts +18 -0
package/dist/index.js
CHANGED
|
@@ -95,6 +95,7 @@ const IOS_PACKET_LENGTH = 128;
|
|
|
95
95
|
const ANDROID_PACKET_LENGTH = 192;
|
|
96
96
|
const ANDROID_DEFAULT_MTU = 23;
|
|
97
97
|
const ClassicServiceUUID = '00000001-0000-1000-8000-00805f9b34fb';
|
|
98
|
+
const Pro2ServiceUUID = 'fffd';
|
|
98
99
|
const OneKeyServices = {
|
|
99
100
|
classic: {
|
|
100
101
|
[ClassicServiceUUID]: {
|
|
@@ -102,6 +103,11 @@ const OneKeyServices = {
|
|
|
102
103
|
writeUuid: '00000002-0000-1000-8000-00805f9b34fb',
|
|
103
104
|
notifyUuid: '00000003-0000-1000-8000-00805f9b34fb',
|
|
104
105
|
},
|
|
106
|
+
[Pro2ServiceUUID]: {
|
|
107
|
+
serviceUuid: Pro2ServiceUUID,
|
|
108
|
+
writeUuid: '00000002-0000-1000-8000-00805f9b34fb',
|
|
109
|
+
notifyUuid: '00000003-0000-1000-8000-00805f9b34fb',
|
|
110
|
+
},
|
|
105
111
|
},
|
|
106
112
|
};
|
|
107
113
|
const bluetoothServices = [];
|
|
@@ -117,7 +123,8 @@ const getInfosForServiceUuid = (serviceUuid, deviceType) => {
|
|
|
117
123
|
return null;
|
|
118
124
|
}
|
|
119
125
|
const normalizedServiceUuid = normalizeBleUuid(serviceUuid);
|
|
120
|
-
const service = (_a = services[serviceUuid]) !== null && _a !== void 0 ? _a : Object.values(services).find(item => normalizeBleUuid(item.serviceUuid) === normalizedServiceUuid
|
|
126
|
+
const service = (_a = services[serviceUuid]) !== null && _a !== void 0 ? _a : Object.values(services).find(item => normalizeBleUuid(item.serviceUuid) === normalizedServiceUuid ||
|
|
127
|
+
getBleUuidKey(item.serviceUuid) === getBleUuidKey(serviceUuid));
|
|
121
128
|
if (!service) {
|
|
122
129
|
return null;
|
|
123
130
|
}
|
|
@@ -138,21 +145,6 @@ const isSameBleUuid = (left, right) => {
|
|
|
138
145
|
function hasWritableCapability(characteristic) {
|
|
139
146
|
return !!(characteristic.isWritableWithResponse || characteristic.isWritableWithoutResponse);
|
|
140
147
|
}
|
|
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
148
|
function resolveProtocolV2PacketCapacity({ platform, iosPacketLength = IOS_PACKET_LENGTH, androidPacketLength = ANDROID_PACKET_LENGTH, mtu, }) {
|
|
157
149
|
if (platform === 'ios') {
|
|
158
150
|
return iosPacketLength;
|
|
@@ -189,7 +181,6 @@ const timer = process.env.NODE_ENV === 'development'
|
|
|
189
181
|
const subscribeBleOn = (bleManager, ms = 1000) => new Promise((resolve, reject) => {
|
|
190
182
|
let done = false;
|
|
191
183
|
const subscription = bleManager.onStateChange(state => {
|
|
192
|
-
console.log('ble state -> ', state);
|
|
193
184
|
if (state === 'PoweredOn') {
|
|
194
185
|
if (done)
|
|
195
186
|
return;
|
|
@@ -261,6 +252,18 @@ class BleTransport {
|
|
|
261
252
|
BleTransport.MAX_RETRIES = 5;
|
|
262
253
|
BleTransport.RETRY_DELAY = 2000;
|
|
263
254
|
|
|
255
|
+
function createTransportCallLog(name, protocol, data) {
|
|
256
|
+
if (name === 'ResourceUpdate' || name === 'ResourceAck') {
|
|
257
|
+
return {
|
|
258
|
+
name,
|
|
259
|
+
protocol,
|
|
260
|
+
file_name: data.file_name,
|
|
261
|
+
hash: data.hash,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
return { name, protocol };
|
|
265
|
+
}
|
|
266
|
+
|
|
264
267
|
const { check, ProtocolV1, parseConfigure } = transport__default["default"];
|
|
265
268
|
const Log = bleLogger;
|
|
266
269
|
const transportCache = {};
|
|
@@ -293,22 +296,14 @@ const getFirmwareUploadWriteRetryType = (error) => {
|
|
|
293
296
|
return /GATT_CONGESTED|status\s*[:=]?\s*143/.test(text) ? 'congested' : null;
|
|
294
297
|
};
|
|
295
298
|
const resolveFirmwareUploadRetryDelay = (attempt, baseDelayMs = 200, maxDelayMs = 1200) => Math.min(baseDelayMs * Math.pow(2, attempt), maxDelayMs);
|
|
296
|
-
const BLE_RESPONSE_TIMEOUT_MS = 30000;
|
|
297
299
|
const PROTOCOL_PROBE_TIMEOUT_MS = 1000;
|
|
298
300
|
const PROTOCOL_V2_PROBE_TIMEOUT_MS = 10000;
|
|
299
|
-
const DEVICE_SCAN_TIMEOUT_MS =
|
|
301
|
+
const DEVICE_SCAN_TIMEOUT_MS = 3000;
|
|
300
302
|
const IOS_NOTIFY_READY_DELAY_MS = 150;
|
|
301
303
|
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
304
|
const DEFAULT_PROTOCOL_V2_BLE_TUNING = {
|
|
306
305
|
iosPacketLength: IOS_PACKET_LENGTH,
|
|
307
306
|
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
307
|
};
|
|
313
308
|
let protocolV2BleTuning = Object.assign({}, DEFAULT_PROTOCOL_V2_BLE_TUNING);
|
|
314
309
|
const normalizePositiveInteger = (value, fallback) => {
|
|
@@ -318,20 +313,15 @@ const normalizePositiveInteger = (value, fallback) => {
|
|
|
318
313
|
return Math.floor(normalized);
|
|
319
314
|
};
|
|
320
315
|
function configureProtocolV2BleTuning(tuning = {}) {
|
|
321
|
-
var _a;
|
|
322
316
|
protocolV2BleTuning = {
|
|
323
317
|
iosPacketLength: normalizePositiveInteger(tuning.iosPacketLength, protocolV2BleTuning.iosPacketLength),
|
|
324
318
|
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
319
|
};
|
|
330
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport]
|
|
320
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] BLE tuning configured', protocolV2BleTuning);
|
|
331
321
|
}
|
|
332
322
|
function resetProtocolV2BleTuning() {
|
|
333
323
|
protocolV2BleTuning = Object.assign({}, DEFAULT_PROTOCOL_V2_BLE_TUNING);
|
|
334
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport]
|
|
324
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] BLE tuning reset', protocolV2BleTuning);
|
|
335
325
|
}
|
|
336
326
|
function getProtocolV2BleTuning() {
|
|
337
327
|
return Object.assign({}, protocolV2BleTuning);
|
|
@@ -371,9 +361,10 @@ const requestAndroidMtu = (device) => __awaiter(void 0, void 0, void 0, function
|
|
|
371
361
|
return device;
|
|
372
362
|
try {
|
|
373
363
|
const mtuDevice = yield device.requestMTU(ANDROID_REQUEST_MTU);
|
|
374
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport]
|
|
364
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] MTU configured', {
|
|
365
|
+
deviceId: device.id,
|
|
375
366
|
requested: ANDROID_REQUEST_MTU,
|
|
376
|
-
|
|
367
|
+
actual: mtuDevice.mtu,
|
|
377
368
|
});
|
|
378
369
|
return mtuDevice;
|
|
379
370
|
}
|
|
@@ -414,9 +405,29 @@ class ReactNativeBleTransport {
|
|
|
414
405
|
this.protocolV2Assemblers = new Map();
|
|
415
406
|
this.protocolV2FrameQueues = new Map();
|
|
416
407
|
this.protocolV2FramePromises = new Map();
|
|
417
|
-
this.
|
|
418
|
-
|
|
408
|
+
this.protocolV2Links = new transport.ProtocolV2LinkManager({
|
|
409
|
+
getSchemas: () => {
|
|
410
|
+
if (!this._messages || !this._messagesV2) {
|
|
411
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.TransportNotConfigured);
|
|
412
|
+
}
|
|
413
|
+
return {
|
|
414
|
+
protocolV1: this._messages,
|
|
415
|
+
protocolV2: this._messagesV2,
|
|
416
|
+
};
|
|
417
|
+
},
|
|
418
|
+
classifyError: () => 'link-fatal',
|
|
419
|
+
onLinkInvalidated: (uuid, reason) => __awaiter(this, void 0, void 0, function* () {
|
|
420
|
+
var _b;
|
|
421
|
+
(_b = this.protocolV2Assemblers.get(uuid)) === null || _b === void 0 ? void 0 : _b.reset();
|
|
422
|
+
this.rejectProtocolV2Frames(uuid, new Error(reason));
|
|
423
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V2 link invalidated:', uuid, reason);
|
|
424
|
+
if (reason.startsWith('Protocol V2 link-fatal error:')) {
|
|
425
|
+
yield this.release(uuid, true);
|
|
426
|
+
}
|
|
427
|
+
}),
|
|
428
|
+
});
|
|
419
429
|
this.monitorTokens = new Map();
|
|
430
|
+
this.disconnectEventTokens = new Map();
|
|
420
431
|
this.nextMonitorToken = 1;
|
|
421
432
|
this.scanTimeout = (_a = options.scanTimeout) !== null && _a !== void 0 ? _a : DEVICE_SCAN_TIMEOUT_MS;
|
|
422
433
|
}
|
|
@@ -430,8 +441,18 @@ class ReactNativeBleTransport {
|
|
|
430
441
|
this._messages = messages;
|
|
431
442
|
}
|
|
432
443
|
configureProtocolV2(signedData) {
|
|
444
|
+
const configuration = typeof signedData === 'string' ? signedData : JSON.stringify(signedData);
|
|
445
|
+
if (this.protocolV2SchemaConfiguration === configuration) {
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
const isReconfiguration = this.protocolV2SchemaConfiguration !== undefined;
|
|
433
449
|
this._messagesV2 = parseConfigure(signedData);
|
|
434
|
-
|
|
450
|
+
this.protocolV2SchemaConfiguration = configuration;
|
|
451
|
+
if (isReconfiguration) {
|
|
452
|
+
this.protocolV2Links
|
|
453
|
+
.invalidateAllLinks('Protocol V2 schema reconfigured')
|
|
454
|
+
.catch(error => Log === null || Log === void 0 ? void 0 : Log.debug('Protocol V2 schema link cleanup failed:', error));
|
|
455
|
+
}
|
|
435
456
|
}
|
|
436
457
|
listen() {
|
|
437
458
|
}
|
|
@@ -524,8 +545,8 @@ class ReactNativeBleTransport {
|
|
|
524
545
|
attachDisconnectSubscription(transport, device, uuid) {
|
|
525
546
|
var _a;
|
|
526
547
|
(_a = transport.disconnectSubscription) === null || _a === void 0 ? void 0 : _a.remove();
|
|
548
|
+
const { monitorToken } = transport;
|
|
527
549
|
transport.disconnectSubscription = device.onDisconnected(() => {
|
|
528
|
-
var _a;
|
|
529
550
|
if (this.firmwareUploadWriteRecoveryIds.has(uuid)) {
|
|
530
551
|
Log === null || Log === void 0 ? void 0 : Log.debug('device disconnect ignored during FirmwareUpload write recovery: ', uuid);
|
|
531
552
|
return;
|
|
@@ -534,13 +555,13 @@ class ReactNativeBleTransport {
|
|
|
534
555
|
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
556
|
return;
|
|
536
557
|
}
|
|
558
|
+
if (this.monitorTokens.get(uuid) !== monitorToken) {
|
|
559
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('device disconnect ignored for stale generation: ', device === null || device === void 0 ? void 0 : device.id);
|
|
560
|
+
return;
|
|
561
|
+
}
|
|
537
562
|
try {
|
|
538
563
|
Log === null || Log === void 0 ? void 0 : Log.debug('device disconnect: ', device === null || device === void 0 ? void 0 : device.id);
|
|
539
|
-
(
|
|
540
|
-
name: device === null || device === void 0 ? void 0 : device.name,
|
|
541
|
-
id: device === null || device === void 0 ? void 0 : device.id,
|
|
542
|
-
connectId: device === null || device === void 0 ? void 0 : device.id,
|
|
543
|
-
});
|
|
564
|
+
this.emitDeviceDisconnect(uuid, device === null || device === void 0 ? void 0 : device.name, monitorToken);
|
|
544
565
|
if (this.runPromise) {
|
|
545
566
|
const error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleConnectedError);
|
|
546
567
|
this.runPromise.reject(error);
|
|
@@ -555,6 +576,22 @@ class ReactNativeBleTransport {
|
|
|
555
576
|
}
|
|
556
577
|
});
|
|
557
578
|
}
|
|
579
|
+
emitDeviceDisconnect(uuid, name, token) {
|
|
580
|
+
var _a;
|
|
581
|
+
if (token === undefined || this.disconnectEventTokens.get(uuid) === token) {
|
|
582
|
+
return;
|
|
583
|
+
}
|
|
584
|
+
if (this.monitorTokens.get(uuid) !== token) {
|
|
585
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('device disconnect event ignored for stale generation: ', uuid);
|
|
586
|
+
return;
|
|
587
|
+
}
|
|
588
|
+
this.disconnectEventTokens.set(uuid, token);
|
|
589
|
+
(_a = this.emitter) === null || _a === void 0 ? void 0 : _a.emit(transport.TRANSPORT_EVENT.DEVICE_DISCONNECT, {
|
|
590
|
+
name,
|
|
591
|
+
id: uuid,
|
|
592
|
+
connectId: uuid,
|
|
593
|
+
});
|
|
594
|
+
}
|
|
558
595
|
reconnectFirmwareUploadTransport(uuid, transport) {
|
|
559
596
|
var _a, _b;
|
|
560
597
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -624,13 +661,12 @@ class ReactNativeBleTransport {
|
|
|
624
661
|
return;
|
|
625
662
|
}
|
|
626
663
|
}
|
|
627
|
-
blePlxManager.startDeviceScan(
|
|
664
|
+
blePlxManager.startDeviceScan(getBluetoothServiceUuids(), {
|
|
628
665
|
allowDuplicates: true,
|
|
629
666
|
scanMode: reactNativeBlePlx.ScanMode.LowLatency,
|
|
630
667
|
}, (error, device) => {
|
|
631
668
|
var _a, _b, _c;
|
|
632
669
|
if (error) {
|
|
633
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('ble scan manager: ', blePlxManager);
|
|
634
670
|
Log === null || Log === void 0 ? void 0 : Log.debug('ble scan error: ', error);
|
|
635
671
|
if ([reactNativeBlePlx.BleErrorCode.BluetoothPoweredOff, reactNativeBlePlx.BleErrorCode.BluetoothInUnknownState].includes(error.errorCode)) {
|
|
636
672
|
reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BlePermissionError));
|
|
@@ -653,22 +689,8 @@ class ReactNativeBleTransport {
|
|
|
653
689
|
const isOneKey = hdShared.isOnekeyDevice((_b = device === null || device === void 0 ? void 0 : device.name) !== null && _b !== void 0 ? _b : null, device === null || device === void 0 ? void 0 : device.id) ||
|
|
654
690
|
hdShared.isOnekeyDevice((_c = device === null || device === void 0 ? void 0 : device.localName) !== null && _c !== void 0 ? _c : null, device === null || device === void 0 ? void 0 : device.id) ||
|
|
655
691
|
hasKnownOneKeyService(device);
|
|
656
|
-
const shouldTraceCandidate = !!displayName && /onekey|bixinkey|pro\s*2|pro\b|touch|^k\d|^t\d/i.test(displayName);
|
|
657
|
-
if (shouldTraceCandidate) {
|
|
658
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] scan candidate', {
|
|
659
|
-
name: device === null || device === void 0 ? void 0 : device.name,
|
|
660
|
-
localName: device === null || device === void 0 ? void 0 : device.localName,
|
|
661
|
-
id: device === null || device === void 0 ? void 0 : device.id,
|
|
662
|
-
serviceUUIDs: device === null || device === void 0 ? void 0 : device.serviceUUIDs,
|
|
663
|
-
accepted: isOneKey,
|
|
664
|
-
});
|
|
665
|
-
}
|
|
666
692
|
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
693
|
addDevice(device);
|
|
671
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('search device end ======================\n');
|
|
672
694
|
}
|
|
673
695
|
else if (displayName && /\bpro\s*2\b/i.test(displayName)) {
|
|
674
696
|
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Pro2-like BLE device was not accepted:', {
|
|
@@ -679,10 +701,15 @@ class ReactNativeBleTransport {
|
|
|
679
701
|
});
|
|
680
702
|
}
|
|
681
703
|
});
|
|
682
|
-
getConnectedDeviceIds(getBluetoothServiceUuids()).then(devices => {
|
|
704
|
+
getConnectedDeviceIds(reactNative.Platform.OS === 'ios' ? getBluetoothServiceUuids() : []).then(devices => {
|
|
683
705
|
for (const device of devices) {
|
|
684
|
-
|
|
685
|
-
|
|
706
|
+
const { serviceUUIDs } = device;
|
|
707
|
+
const hasCachedServiceUuid = Boolean(serviceUUIDs === null || serviceUUIDs === void 0 ? void 0 : serviceUUIDs.length);
|
|
708
|
+
const keepDevice = reactNative.Platform.OS === 'ios' || hasCachedServiceUuid;
|
|
709
|
+
if (keepDevice) {
|
|
710
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('search connected peripheral: ', device.id);
|
|
711
|
+
addDevice(device);
|
|
712
|
+
}
|
|
686
713
|
}
|
|
687
714
|
});
|
|
688
715
|
const addDevice = (device) => {
|
|
@@ -694,6 +721,12 @@ class ReactNativeBleTransport {
|
|
|
694
721
|
this.deviceProtocolHints.set(device.id, protocolHint);
|
|
695
722
|
}
|
|
696
723
|
deviceList.push(Object.assign(Object.assign({}, device), { name: displayName, commType: 'ble' }));
|
|
724
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] OneKey BLE device discovered', {
|
|
725
|
+
deviceId: device.id,
|
|
726
|
+
name: displayName,
|
|
727
|
+
serviceUUIDs: device.serviceUUIDs,
|
|
728
|
+
protocolHint,
|
|
729
|
+
});
|
|
697
730
|
}
|
|
698
731
|
};
|
|
699
732
|
timer.timeout(() => {
|
|
@@ -704,7 +737,7 @@ class ReactNativeBleTransport {
|
|
|
704
737
|
});
|
|
705
738
|
}
|
|
706
739
|
acquire(input) {
|
|
707
|
-
var _a
|
|
740
|
+
var _a;
|
|
708
741
|
return __awaiter(this, void 0, void 0, function* () {
|
|
709
742
|
const { uuid, forceCleanRunPromise, expectedProtocol } = input;
|
|
710
743
|
if (!uuid) {
|
|
@@ -729,7 +762,6 @@ class ReactNativeBleTransport {
|
|
|
729
762
|
this.runPromise.reject(error);
|
|
730
763
|
this.rejectAllProtocolV2Frames(error);
|
|
731
764
|
this.runPromise = null;
|
|
732
|
-
this.activeProtocolV2Call = null;
|
|
733
765
|
Log === null || Log === void 0 ? void 0 : Log.debug('Force clean Bluetooth run promise, forceCleanRunPromise: ', forceCleanRunPromise);
|
|
734
766
|
}
|
|
735
767
|
const blePlxManager = yield this.getPlxManager();
|
|
@@ -831,7 +863,7 @@ class ReactNativeBleTransport {
|
|
|
831
863
|
this.monitorTokens.set(uuid, monitorToken);
|
|
832
864
|
transport$1.notifySubscription = this._monitorCharacteristic(transport$1.notifyCharacteristic, uuid, monitorToken, notifyTransactionId);
|
|
833
865
|
transportCache[uuid] = transport$1;
|
|
834
|
-
this.protocolV2Assemblers.set(uuid, new transport.ProtocolV2FrameAssembler());
|
|
866
|
+
this.protocolV2Assemblers.set(uuid, new transport.ProtocolV2FrameAssembler(transport.PROTOCOL_V2_BLE_FRAME_MAX_BYTES));
|
|
835
867
|
if (reactNative.Platform.OS === 'ios') {
|
|
836
868
|
yield new Promise(resolve => {
|
|
837
869
|
setTimeout(resolve, IOS_NOTIFY_READY_DELAY_MS);
|
|
@@ -841,11 +873,6 @@ class ReactNativeBleTransport {
|
|
|
841
873
|
yield delay(ANDROID_NOTIFY_READY_DELAY_MS);
|
|
842
874
|
}
|
|
843
875
|
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
876
|
this.attachDisconnectSubscription(transport$1, device, uuid);
|
|
850
877
|
return { uuid, protocolType };
|
|
851
878
|
});
|
|
@@ -854,7 +881,7 @@ class ReactNativeBleTransport {
|
|
|
854
881
|
let bufferLength = 0;
|
|
855
882
|
let buffer$1 = [];
|
|
856
883
|
const subscription = characteristic.monitor((error, c) => {
|
|
857
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
884
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
|
|
858
885
|
const isCurrentMonitor = this.monitorTokens.get(uuid) === monitorToken;
|
|
859
886
|
if (error) {
|
|
860
887
|
Log === null || Log === void 0 ? void 0 : Log.debug(`error monitor ${characteristic.uuid}, deviceId: ${characteristic.deviceID}: ${error}`);
|
|
@@ -866,19 +893,37 @@ class ReactNativeBleTransport {
|
|
|
866
893
|
Log === null || Log === void 0 ? void 0 : Log.debug('monitor error ignored for stale transport: ', uuid, notifyTransactionId);
|
|
867
894
|
return;
|
|
868
895
|
}
|
|
869
|
-
if (this.
|
|
870
|
-
let
|
|
896
|
+
if (this.deviceProtocol.get(uuid) === 'V2') {
|
|
897
|
+
let errorCode = hdShared.HardwareErrorCode.BleCharacteristicNotifyError;
|
|
871
898
|
if ((_a = error.reason) === null || _a === void 0 ? void 0 : _a.includes('The connection has timed out unexpectedly')) {
|
|
872
|
-
|
|
899
|
+
errorCode = hdShared.HardwareErrorCode.BleTimeoutError;
|
|
873
900
|
}
|
|
874
|
-
if ((_b = error.reason) === null || _b === void 0 ? void 0 : _b.includes('Encryption is insufficient')) {
|
|
875
|
-
|
|
901
|
+
else if ((_b = error.reason) === null || _b === void 0 ? void 0 : _b.includes('Encryption is insufficient')) {
|
|
902
|
+
errorCode = hdShared.HardwareErrorCode.BleDeviceBondError;
|
|
876
903
|
}
|
|
877
|
-
if (((_c = error.reason) === null || _c === void 0 ? void 0 : _c.includes('Cannot write client characteristic config descriptor')) ||
|
|
904
|
+
else if (((_c = error.reason) === null || _c === void 0 ? void 0 : _c.includes('Cannot write client characteristic config descriptor')) ||
|
|
878
905
|
((_d = error.reason) === null || _d === void 0 ? void 0 : _d.includes('Cannot find client characteristic config descriptor')) ||
|
|
879
906
|
((_e = error.reason) === null || _e === void 0 ? void 0 : _e.includes('The handle is invalid')) ||
|
|
880
907
|
((_f = error.reason) === null || _f === void 0 ? void 0 : _f.includes('Writing is not permitted')) ||
|
|
881
908
|
((_g = error.reason) === null || _g === void 0 ? void 0 : _g.includes('notify change failed for device'))) {
|
|
909
|
+
errorCode = hdShared.HardwareErrorCode.BleCharacteristicNotifyChangeFailure;
|
|
910
|
+
}
|
|
911
|
+
this.rejectProtocolV2Frames(uuid, hdShared.ERRORS.TypedError(errorCode));
|
|
912
|
+
return;
|
|
913
|
+
}
|
|
914
|
+
if (this.runPromise) {
|
|
915
|
+
let ERROR = hdShared.HardwareErrorCode.BleCharacteristicNotifyError;
|
|
916
|
+
if ((_h = error.reason) === null || _h === void 0 ? void 0 : _h.includes('The connection has timed out unexpectedly')) {
|
|
917
|
+
ERROR = hdShared.HardwareErrorCode.BleTimeoutError;
|
|
918
|
+
}
|
|
919
|
+
if ((_j = error.reason) === null || _j === void 0 ? void 0 : _j.includes('Encryption is insufficient')) {
|
|
920
|
+
ERROR = hdShared.HardwareErrorCode.BleDeviceBondError;
|
|
921
|
+
}
|
|
922
|
+
if (((_k = error.reason) === null || _k === void 0 ? void 0 : _k.includes('Cannot write client characteristic config descriptor')) ||
|
|
923
|
+
((_l = error.reason) === null || _l === void 0 ? void 0 : _l.includes('Cannot find client characteristic config descriptor')) ||
|
|
924
|
+
((_m = error.reason) === null || _m === void 0 ? void 0 : _m.includes('The handle is invalid')) ||
|
|
925
|
+
((_o = error.reason) === null || _o === void 0 ? void 0 : _o.includes('Writing is not permitted')) ||
|
|
926
|
+
((_p = error.reason) === null || _p === void 0 ? void 0 : _p.includes('notify change failed for device'))) {
|
|
882
927
|
const notifyError = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleCharacteristicNotifyChangeFailure);
|
|
883
928
|
this.runPromise.reject(notifyError);
|
|
884
929
|
this.rejectAllProtocolV2Frames(notifyError);
|
|
@@ -907,7 +952,7 @@ class ReactNativeBleTransport {
|
|
|
907
952
|
return;
|
|
908
953
|
}
|
|
909
954
|
if (protocol === 'V2') {
|
|
910
|
-
this.handleProtocolV2Notification(uuid, new Uint8Array(data));
|
|
955
|
+
this.handleProtocolV2Notification(uuid, monitorToken, new Uint8Array(data));
|
|
911
956
|
return;
|
|
912
957
|
}
|
|
913
958
|
if (isHeaderChunk(data)) {
|
|
@@ -921,28 +966,32 @@ class ReactNativeBleTransport {
|
|
|
921
966
|
const value = buffer.Buffer.from(buffer$1);
|
|
922
967
|
bufferLength = 0;
|
|
923
968
|
buffer$1 = [];
|
|
924
|
-
(
|
|
969
|
+
(_q = this.runPromise) === null || _q === void 0 ? void 0 : _q.resolve(value.toString('hex'));
|
|
925
970
|
}
|
|
926
971
|
}
|
|
927
972
|
catch (error) {
|
|
928
973
|
Log === null || Log === void 0 ? void 0 : Log.debug('monitor data error: ', error);
|
|
929
974
|
const notifyError = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleWriteCharacteristicError);
|
|
930
|
-
(
|
|
931
|
-
|
|
975
|
+
if (this.deviceProtocol.get(uuid) === 'V2') {
|
|
976
|
+
this.rejectProtocolV2Frames(uuid, notifyError);
|
|
977
|
+
}
|
|
978
|
+
else {
|
|
979
|
+
(_r = this.runPromise) === null || _r === void 0 ? void 0 : _r.reject(notifyError);
|
|
980
|
+
}
|
|
932
981
|
}
|
|
933
982
|
}, notifyTransactionId);
|
|
934
983
|
return subscription;
|
|
935
984
|
}
|
|
936
985
|
release(uuid, onclose = false) {
|
|
937
|
-
var _a, _b, _c, _d, _e, _f, _g
|
|
986
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
938
987
|
return __awaiter(this, void 0, void 0, function* () {
|
|
939
988
|
const transport = transportCache[uuid];
|
|
989
|
+
yield this.protocolV2Links.invalidateLink(uuid, 'React Native BLE transport released');
|
|
940
990
|
if (this.runPromise) {
|
|
941
991
|
const error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleForceCleanRunPromise);
|
|
942
992
|
this.runPromise.reject(error);
|
|
943
993
|
this.runPromise = null;
|
|
944
994
|
this.rejectAllProtocolV2Frames(error);
|
|
945
|
-
this.activeProtocolV2Call = null;
|
|
946
995
|
}
|
|
947
996
|
else {
|
|
948
997
|
this.resetProtocolV2Frames(uuid);
|
|
@@ -950,9 +999,6 @@ class ReactNativeBleTransport {
|
|
|
950
999
|
if (reactNative.Platform.OS === 'android' && !onclose && transport) {
|
|
951
1000
|
(_a = this.protocolV2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
|
|
952
1001
|
this.resetProtocolV2Frames(uuid);
|
|
953
|
-
if (((_b = this.activeProtocolV2Call) === null || _b === void 0 ? void 0 : _b.uuid) === uuid) {
|
|
954
|
-
this.activeProtocolV2Call = null;
|
|
955
|
-
}
|
|
956
1002
|
return Promise.resolve(true);
|
|
957
1003
|
}
|
|
958
1004
|
if (transport) {
|
|
@@ -960,14 +1006,14 @@ class ReactNativeBleTransport {
|
|
|
960
1006
|
this.monitorTokens.delete(uuid);
|
|
961
1007
|
}
|
|
962
1008
|
Log === null || Log === void 0 ? void 0 : Log.debug('release: removing disconnect subscription for device: ', uuid);
|
|
963
|
-
(
|
|
1009
|
+
(_b = transport.disconnectSubscription) === null || _b === void 0 ? void 0 : _b.remove();
|
|
964
1010
|
transport.disconnectSubscription = undefined;
|
|
965
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('release: removing notify subscription, characteristic: ', (
|
|
966
|
-
(
|
|
1011
|
+
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);
|
|
1012
|
+
(_d = transport.notifySubscription) === null || _d === void 0 ? void 0 : _d.remove();
|
|
967
1013
|
transport.notifySubscription = undefined;
|
|
968
1014
|
if (transport.notifyTransactionId) {
|
|
969
1015
|
try {
|
|
970
|
-
yield ((
|
|
1016
|
+
yield ((_e = this.blePlxManager) === null || _e === void 0 ? void 0 : _e.cancelTransaction(transport.notifyTransactionId));
|
|
971
1017
|
}
|
|
972
1018
|
catch (e) {
|
|
973
1019
|
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 +1022,11 @@ class ReactNativeBleTransport {
|
|
|
976
1022
|
delete transportCache[uuid];
|
|
977
1023
|
}
|
|
978
1024
|
this.deviceProtocol.delete(uuid);
|
|
979
|
-
this.
|
|
980
|
-
(_g = this.protocolV2Assemblers.get(uuid)) === null || _g === void 0 ? void 0 : _g.reset();
|
|
1025
|
+
(_f = this.protocolV2Assemblers.get(uuid)) === null || _f === void 0 ? void 0 : _f.reset();
|
|
981
1026
|
this.protocolV2Assemblers.delete(uuid);
|
|
982
1027
|
this.resetProtocolV2Frames(uuid);
|
|
983
1028
|
try {
|
|
984
|
-
yield ((
|
|
1029
|
+
yield ((_g = this.blePlxManager) === null || _g === void 0 ? void 0 : _g.cancelTransaction(uuid));
|
|
985
1030
|
}
|
|
986
1031
|
catch (e) {
|
|
987
1032
|
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 +1047,18 @@ class ReactNativeBleTransport {
|
|
|
1002
1047
|
if (this._messages == null) {
|
|
1003
1048
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.TransportNotConfigured);
|
|
1004
1049
|
}
|
|
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
1050
|
const protocol = this.getProtocolType(uuid);
|
|
1011
1051
|
if (!protocol) {
|
|
1012
1052
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Device protocol has not been detected for ${uuid}`);
|
|
1013
1053
|
}
|
|
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
|
-
}
|
|
1054
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('transport call', createTransportCallLog(name, protocol, data));
|
|
1026
1055
|
if (protocol === 'V2') {
|
|
1027
1056
|
return this.callProtocolV2(uuid, name, data, options);
|
|
1028
1057
|
}
|
|
1058
|
+
const forceRun = name === 'Initialize' || name === 'Cancel';
|
|
1059
|
+
if (this.runPromise && !forceRun) {
|
|
1060
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.TransportCallInProgress);
|
|
1061
|
+
}
|
|
1029
1062
|
return this.callProtocolV1(uuid, name, data, options);
|
|
1030
1063
|
});
|
|
1031
1064
|
}
|
|
@@ -1101,7 +1134,7 @@ class ReactNativeBleTransport {
|
|
|
1101
1134
|
});
|
|
1102
1135
|
}
|
|
1103
1136
|
else if (name === 'FirmwareUpload') {
|
|
1104
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport]
|
|
1137
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Firmware upload transport configured', {
|
|
1105
1138
|
packetCapacity: FIRMWARE_UPLOAD_WRITE_PACKET_CAPACITY,
|
|
1106
1139
|
burstSize: FIRMWARE_UPLOAD_WRITE_BURST_SIZE,
|
|
1107
1140
|
pauseMs: FIRMWARE_UPLOAD_WRITE_PAUSE_MS,
|
|
@@ -1190,7 +1223,6 @@ class ReactNativeBleTransport {
|
|
|
1190
1223
|
if (typeof response !== 'string') {
|
|
1191
1224
|
throw new Error('Returning data is not string.');
|
|
1192
1225
|
}
|
|
1193
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('receive data: ', response);
|
|
1194
1226
|
const jsonData = ProtocolV1.decodeMessage(messages, response);
|
|
1195
1227
|
return check.call(jsonData);
|
|
1196
1228
|
}
|
|
@@ -1216,10 +1248,11 @@ class ReactNativeBleTransport {
|
|
|
1216
1248
|
this.stopped = true;
|
|
1217
1249
|
}
|
|
1218
1250
|
disconnect(session) {
|
|
1219
|
-
var _a, _b, _c, _d, _e
|
|
1251
|
+
var _a, _b, _c, _d, _e;
|
|
1220
1252
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1221
|
-
|
|
1253
|
+
yield this.protocolV2Links.invalidateLink(session, 'React Native BLE transport disconnected');
|
|
1222
1254
|
const transport = transportCache[session];
|
|
1255
|
+
const monitorToken = (_a = transport === null || transport === void 0 ? void 0 : transport.monitorToken) !== null && _a !== void 0 ? _a : this.monitorTokens.get(session);
|
|
1223
1256
|
if (transport === null || transport === void 0 ? void 0 : transport.disconnectSubscription) {
|
|
1224
1257
|
try {
|
|
1225
1258
|
Log === null || Log === void 0 ? void 0 : Log.debug('disconnect: removing disconnect subscription');
|
|
@@ -1232,7 +1265,7 @@ class ReactNativeBleTransport {
|
|
|
1232
1265
|
}
|
|
1233
1266
|
if (transport === null || transport === void 0 ? void 0 : transport.notifySubscription) {
|
|
1234
1267
|
try {
|
|
1235
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('disconnect: removing notify subscription, characteristic: ', (
|
|
1268
|
+
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
1269
|
transport.notifySubscription.remove();
|
|
1237
1270
|
transport.notifySubscription = undefined;
|
|
1238
1271
|
}
|
|
@@ -1242,7 +1275,7 @@ class ReactNativeBleTransport {
|
|
|
1242
1275
|
}
|
|
1243
1276
|
if (session) {
|
|
1244
1277
|
try {
|
|
1245
|
-
yield ((
|
|
1278
|
+
yield ((_c = this.blePlxManager) === null || _c === void 0 ? void 0 : _c.cancelTransaction(session));
|
|
1246
1279
|
}
|
|
1247
1280
|
catch (e) {
|
|
1248
1281
|
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 +1290,7 @@ class ReactNativeBleTransport {
|
|
|
1257
1290
|
}
|
|
1258
1291
|
}
|
|
1259
1292
|
try {
|
|
1260
|
-
yield ((
|
|
1293
|
+
yield ((_d = this.blePlxManager) === null || _d === void 0 ? void 0 : _d.cancelDeviceConnection(session));
|
|
1261
1294
|
}
|
|
1262
1295
|
catch (e) {
|
|
1263
1296
|
Log === null || Log === void 0 ? void 0 : Log.debug('resetSession: manager.cancelDeviceConnection error (ignored): ', (e === null || e === void 0 ? void 0 : e.message) || e);
|
|
@@ -1269,19 +1302,15 @@ class ReactNativeBleTransport {
|
|
|
1269
1302
|
this.deviceProtocolHints.delete(session);
|
|
1270
1303
|
this.protocolV2Assemblers.delete(session);
|
|
1271
1304
|
this.resetProtocolV2Frames(session);
|
|
1272
|
-
if (((_d = this.activeProtocolV2Call) === null || _d === void 0 ? void 0 : _d.uuid) === session) {
|
|
1273
|
-
this.activeProtocolV2Call = null;
|
|
1274
|
-
}
|
|
1275
1305
|
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
|
-
});
|
|
1306
|
+
this.emitDeviceDisconnect(session, (_e = transport === null || transport === void 0 ? void 0 : transport.device) === null || _e === void 0 ? void 0 : _e.name, monitorToken);
|
|
1281
1307
|
}
|
|
1282
1308
|
catch (e) {
|
|
1283
1309
|
Log === null || Log === void 0 ? void 0 : Log.error('resetSession: emit disconnect event error: ', e);
|
|
1284
1310
|
}
|
|
1311
|
+
if (monitorToken !== undefined && this.monitorTokens.get(session) === monitorToken) {
|
|
1312
|
+
this.monitorTokens.delete(session);
|
|
1313
|
+
}
|
|
1285
1314
|
yield new Promise(resolve => setTimeout(() => resolve(), 100));
|
|
1286
1315
|
});
|
|
1287
1316
|
}
|
|
@@ -1313,15 +1342,26 @@ class ReactNativeBleTransport {
|
|
|
1313
1342
|
if (expectedProtocol === 'V1') {
|
|
1314
1343
|
if (yield this.probeProtocolV1(uuid)) {
|
|
1315
1344
|
this.deviceProtocol.set(uuid, 'V1');
|
|
1316
|
-
Log === null || Log === void 0 ? void 0 : Log.debug(
|
|
1345
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] protocol detected', {
|
|
1346
|
+
deviceId: uuid,
|
|
1347
|
+
protocol: 'V1',
|
|
1348
|
+
source: 'expected',
|
|
1349
|
+
});
|
|
1317
1350
|
return 'V1';
|
|
1318
1351
|
}
|
|
1319
1352
|
throw this.createProtocolMismatchError(expectedProtocol);
|
|
1320
1353
|
}
|
|
1321
1354
|
if (expectedProtocol === 'V2') {
|
|
1322
|
-
this.
|
|
1323
|
-
|
|
1324
|
-
|
|
1355
|
+
if (yield this.probeProtocolV2(uuid)) {
|
|
1356
|
+
this.deviceProtocol.set(uuid, 'V2');
|
|
1357
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] protocol detected', {
|
|
1358
|
+
deviceId: uuid,
|
|
1359
|
+
protocol: 'V2',
|
|
1360
|
+
source: 'expected',
|
|
1361
|
+
});
|
|
1362
|
+
return 'V2';
|
|
1363
|
+
}
|
|
1364
|
+
throw this.createProtocolMismatchError(expectedProtocol);
|
|
1325
1365
|
}
|
|
1326
1366
|
const probeOrder = protocolHint === 'V2' || this.deviceProtocol.get(uuid) === 'V2' ? ['V2', 'V1'] : ['V1', 'V2'];
|
|
1327
1367
|
for (let i = 0; i < probeOrder.length; i += 1) {
|
|
@@ -1332,7 +1372,11 @@ class ReactNativeBleTransport {
|
|
|
1332
1372
|
const detected = protocol === 'V1' ? yield this.probeProtocolV1(uuid) : yield this.probeProtocolV2(uuid);
|
|
1333
1373
|
if (detected) {
|
|
1334
1374
|
this.deviceProtocol.set(uuid, protocol);
|
|
1335
|
-
Log === null || Log === void 0 ? void 0 : Log.debug(
|
|
1375
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] protocol detected', {
|
|
1376
|
+
deviceId: uuid,
|
|
1377
|
+
protocol,
|
|
1378
|
+
source: 'probe',
|
|
1379
|
+
});
|
|
1336
1380
|
return protocol;
|
|
1337
1381
|
}
|
|
1338
1382
|
}
|
|
@@ -1341,14 +1385,12 @@ class ReactNativeBleTransport {
|
|
|
1341
1385
|
});
|
|
1342
1386
|
}
|
|
1343
1387
|
resetProbeStateAfterProtocolProbe(uuid, protocol) {
|
|
1344
|
-
var _a, _b, _c
|
|
1388
|
+
var _a, _b, _c;
|
|
1345
1389
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1346
1390
|
const transport = transportCache[uuid];
|
|
1391
|
+
yield this.protocolV2Links.invalidateLink(uuid, `Reset notify state after Protocol ${protocol} probe`);
|
|
1347
1392
|
(_a = this.protocolV2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
|
|
1348
1393
|
this.resetProtocolV2Frames(uuid);
|
|
1349
|
-
if (((_b = this.activeProtocolV2Call) === null || _b === void 0 ? void 0 : _b.uuid) === uuid) {
|
|
1350
|
-
this.activeProtocolV2Call = null;
|
|
1351
|
-
}
|
|
1352
1394
|
if (this.runPromise) {
|
|
1353
1395
|
const error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleForceCleanRunPromise);
|
|
1354
1396
|
this.runPromise.reject(error);
|
|
@@ -1360,11 +1402,11 @@ class ReactNativeBleTransport {
|
|
|
1360
1402
|
if (this.monitorTokens.get(uuid) === transport.monitorToken) {
|
|
1361
1403
|
this.monitorTokens.delete(uuid);
|
|
1362
1404
|
}
|
|
1363
|
-
(
|
|
1405
|
+
(_b = transport.notifySubscription) === null || _b === void 0 ? void 0 : _b.remove();
|
|
1364
1406
|
transport.notifySubscription = undefined;
|
|
1365
1407
|
if (previousNotifyTransactionId) {
|
|
1366
1408
|
try {
|
|
1367
|
-
yield ((
|
|
1409
|
+
yield ((_c = this.blePlxManager) === null || _c === void 0 ? void 0 : _c.cancelTransaction(previousNotifyTransactionId));
|
|
1368
1410
|
}
|
|
1369
1411
|
catch (error) {
|
|
1370
1412
|
Log === null || Log === void 0 ? void 0 : Log.debug(`[ReactNativeBleTransport] cancel notify after Protocol ${protocol} probe failed:`, (error === null || error === void 0 ? void 0 : error.message) || error);
|
|
@@ -1426,14 +1468,10 @@ class ReactNativeBleTransport {
|
|
|
1426
1468
|
return detected;
|
|
1427
1469
|
});
|
|
1428
1470
|
}
|
|
1429
|
-
handleProtocolV2Notification(uuid, data) {
|
|
1430
|
-
var _a, _b, _c;
|
|
1471
|
+
handleProtocolV2Notification(uuid, monitorToken, data) {
|
|
1431
1472
|
try {
|
|
1432
|
-
if (
|
|
1433
|
-
(_b = this.protocolV2Assemblers.get(uuid)) === null || _b === void 0 ? void 0 : _b.reset();
|
|
1434
|
-
this.resetProtocolV2Frames(uuid);
|
|
1473
|
+
if (this.monitorTokens.get(uuid) !== monitorToken)
|
|
1435
1474
|
return;
|
|
1436
|
-
}
|
|
1437
1475
|
if (data.length === 0)
|
|
1438
1476
|
return;
|
|
1439
1477
|
const assembler = this.protocolV2Assemblers.get(uuid);
|
|
@@ -1446,8 +1484,10 @@ class ReactNativeBleTransport {
|
|
|
1446
1484
|
catch (error) {
|
|
1447
1485
|
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V2 notification error:', error);
|
|
1448
1486
|
const notifyError = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleWriteCharacteristicError);
|
|
1449
|
-
|
|
1450
|
-
this.
|
|
1487
|
+
this.rejectProtocolV2Frames(uuid, notifyError);
|
|
1488
|
+
this.protocolV2Links
|
|
1489
|
+
.invalidateLink(uuid, `Protocol V2 notification error: ${error}`)
|
|
1490
|
+
.catch(invalidateError => Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V2 notify cleanup failed:', invalidateError));
|
|
1451
1491
|
}
|
|
1452
1492
|
}
|
|
1453
1493
|
getProtocolV2FrameQueue(uuid) {
|
|
@@ -1478,9 +1518,13 @@ class ReactNativeBleTransport {
|
|
|
1478
1518
|
this.protocolV2FrameQueues.delete(uuid);
|
|
1479
1519
|
this.protocolV2FramePromises.delete(uuid);
|
|
1480
1520
|
}
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1521
|
+
rejectProtocolV2Frames(uuid, error) {
|
|
1522
|
+
this.protocolV2FrameQueues.delete(uuid);
|
|
1523
|
+
const framePromise = this.protocolV2FramePromises.get(uuid);
|
|
1524
|
+
if (framePromise) {
|
|
1525
|
+
this.protocolV2FramePromises.delete(uuid);
|
|
1526
|
+
framePromise.reject(error);
|
|
1527
|
+
}
|
|
1484
1528
|
}
|
|
1485
1529
|
readProtocolV2Frame(uuid) {
|
|
1486
1530
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -1500,140 +1544,124 @@ class ReactNativeBleTransport {
|
|
|
1500
1544
|
}
|
|
1501
1545
|
});
|
|
1502
1546
|
}
|
|
1503
|
-
|
|
1547
|
+
writeProtocolV2Packet(transport, base64, context, assertCurrentGeneration) {
|
|
1548
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
1549
|
+
let attempt = 0;
|
|
1550
|
+
for (;;) {
|
|
1551
|
+
assertCurrentGeneration();
|
|
1552
|
+
if (context.signal.aborted) {
|
|
1553
|
+
throw new Error(`Protocol V2 BLE write aborted for ${context.messageName}`);
|
|
1554
|
+
}
|
|
1555
|
+
try {
|
|
1556
|
+
yield transport.writeCharacteristic.writeWithoutResponse(base64);
|
|
1557
|
+
assertCurrentGeneration();
|
|
1558
|
+
return;
|
|
1559
|
+
}
|
|
1560
|
+
catch (error) {
|
|
1561
|
+
if (getFirmwareUploadWriteRetryType(error) !== 'congested' ||
|
|
1562
|
+
attempt >= FIRMWARE_UPLOAD_WRITE_MAX_RETRIES) {
|
|
1563
|
+
throw error;
|
|
1564
|
+
}
|
|
1565
|
+
const delayMs = resolveFirmwareUploadRetryDelay(attempt);
|
|
1566
|
+
attempt += 1;
|
|
1567
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V2 congested write retry:', {
|
|
1568
|
+
name: context.messageName,
|
|
1569
|
+
attempt,
|
|
1570
|
+
delayMs,
|
|
1571
|
+
});
|
|
1572
|
+
yield delay(delayMs);
|
|
1573
|
+
}
|
|
1574
|
+
}
|
|
1575
|
+
});
|
|
1576
|
+
}
|
|
1577
|
+
writeProtocolV2Frame(transport$1, frame, context, assertCurrentGeneration) {
|
|
1504
1578
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1505
1579
|
const tuning = getProtocolV2BleTuning();
|
|
1506
1580
|
const packetCapacity = resolveProtocolV2PacketCapacity({
|
|
1507
1581
|
platform: reactNative.Platform.OS,
|
|
1508
1582
|
iosPacketLength: tuning.iosPacketLength,
|
|
1509
1583
|
androidPacketLength: tuning.androidPacketLength,
|
|
1510
|
-
mtu: reactNative.Platform.OS === 'android' ? transport.mtuSize : undefined,
|
|
1584
|
+
mtu: reactNative.Platform.OS === 'android' ? transport$1.mtuSize : undefined,
|
|
1585
|
+
});
|
|
1586
|
+
yield transport.writeProtocolV2BleFrame({
|
|
1587
|
+
frame,
|
|
1588
|
+
packetCapacity,
|
|
1589
|
+
assertActive: assertCurrentGeneration,
|
|
1590
|
+
signal: context.signal,
|
|
1591
|
+
abortMessage: `Protocol V2 BLE write aborted for ${context.messageName}`,
|
|
1592
|
+
burstSize: FIRMWARE_UPLOAD_WRITE_BURST_SIZE,
|
|
1593
|
+
burstPauseMs: FIRMWARE_UPLOAD_WRITE_PAUSE_MS,
|
|
1594
|
+
flushDelayMs: FIRMWARE_UPLOAD_WRITE_FLUSH_DELAY_MS,
|
|
1595
|
+
wait: delay,
|
|
1596
|
+
writePacket: packet => this.writeProtocolV2Packet(transport$1, buffer.Buffer.from(packet).toString('base64'), context, assertCurrentGeneration),
|
|
1511
1597
|
});
|
|
1512
|
-
const writeWithResponse = !!(options === null || options === void 0 ? void 0 : options.writeWithResponse) || (!!(options === null || options === void 0 ? void 0 : options.highVolume) && tuning.highVolumeWriteWithResponse);
|
|
1513
|
-
const writeMode = resolveBleWriteMode(transport.writeCharacteristic, writeWithResponse ? 'withResponse' : 'withoutResponse');
|
|
1514
|
-
const shouldThrottle = !!(options === null || options === void 0 ? void 0 : options.highVolume) && writeMode === 'withoutResponse';
|
|
1515
|
-
let packetsWritten = 0;
|
|
1516
|
-
try {
|
|
1517
|
-
for (let offset = 0; offset < frame.length; offset += packetCapacity) {
|
|
1518
|
-
const chunk = frame.slice(offset, offset + packetCapacity);
|
|
1519
|
-
const base64 = buffer.Buffer.from(chunk).toString('base64');
|
|
1520
|
-
if (writeMode === 'withResponse') {
|
|
1521
|
-
yield transport.writeCharacteristic.writeWithResponse(base64);
|
|
1522
|
-
}
|
|
1523
|
-
else {
|
|
1524
|
-
yield transport.writeCharacteristic.writeWithoutResponse(base64);
|
|
1525
|
-
}
|
|
1526
|
-
packetsWritten += 1;
|
|
1527
|
-
if (shouldThrottle &&
|
|
1528
|
-
packetsWritten % tuning.highVolumeWriteBurstSize === 0 &&
|
|
1529
|
-
offset + packetCapacity < frame.length) {
|
|
1530
|
-
yield delay(tuning.highVolumeWritePauseMs);
|
|
1531
|
-
}
|
|
1532
|
-
}
|
|
1533
|
-
if (shouldThrottle) {
|
|
1534
|
-
yield delay(tuning.highVolumeWriteFlushDelayMs);
|
|
1535
|
-
}
|
|
1536
|
-
}
|
|
1537
|
-
catch (error) {
|
|
1538
|
-
if ((options === null || options === void 0 ? void 0 : options.highVolume) && !writeWithResponse && packetsWritten === 0) {
|
|
1539
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V2 high-volume writeWithoutResponse failed before data was sent, fallback to writeWithResponse:', error);
|
|
1540
|
-
yield this.writeProtocolV2Frame(transport, frame, {
|
|
1541
|
-
highVolume: true,
|
|
1542
|
-
writeWithResponse: true,
|
|
1543
|
-
});
|
|
1544
|
-
return;
|
|
1545
|
-
}
|
|
1546
|
-
throw error;
|
|
1547
|
-
}
|
|
1548
1598
|
});
|
|
1549
1599
|
}
|
|
1550
1600
|
callProtocolV2(uuid, name, data, options) {
|
|
1551
|
-
var _a, _b, _c, _d;
|
|
1552
1601
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1553
1602
|
if (!this._messages || !this._messagesV2) {
|
|
1554
1603
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.TransportNotConfigured);
|
|
1555
1604
|
}
|
|
1556
|
-
const
|
|
1557
|
-
if (this.runPromise) {
|
|
1558
|
-
if (!forceRun) {
|
|
1559
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.TransportCallInProgress);
|
|
1560
|
-
}
|
|
1561
|
-
const error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleForceCleanRunPromise);
|
|
1562
|
-
this.runPromise.reject(error);
|
|
1563
|
-
this.rejectAllProtocolV2Frames(error);
|
|
1564
|
-
this.runPromise = null;
|
|
1565
|
-
this.activeProtocolV2Call = null;
|
|
1566
|
-
}
|
|
1567
|
-
const transport$1 = this.getCachedTransport(uuid);
|
|
1568
|
-
const runPromise = hdShared.createDeferred();
|
|
1569
|
-
runPromise.promise.catch(() => undefined);
|
|
1570
|
-
this.runPromise = runPromise;
|
|
1571
|
-
const callToken = this.nextProtocolV2CallToken++;
|
|
1572
|
-
this.activeProtocolV2Call = { uuid, token: callToken };
|
|
1573
|
-
(_a = this.protocolV2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
|
|
1574
|
-
this.resetProtocolV2Frames(uuid);
|
|
1575
|
-
let completed = false;
|
|
1576
|
-
const callOptions = Object.assign(Object.assign({}, options), { timeoutMs: (_b = options === null || options === void 0 ? void 0 : options.timeoutMs) !== null && _b !== void 0 ? _b : BLE_RESPONSE_TIMEOUT_MS });
|
|
1605
|
+
const callOptions = options;
|
|
1577
1606
|
const highVolumeWrite = transport.LogBlockCommand.has(name);
|
|
1578
1607
|
if (highVolumeWrite) {
|
|
1579
1608
|
const tuning = getProtocolV2BleTuning();
|
|
1580
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V2 high-volume write
|
|
1609
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V2 high-volume write configured', {
|
|
1610
|
+
name,
|
|
1611
|
+
writeMode: 'withoutResponse',
|
|
1581
1612
|
packetCapacity: reactNative.Platform.OS === 'ios' ? tuning.iosPacketLength : tuning.androidPacketLength,
|
|
1582
|
-
burstSize: tuning.highVolumeWriteBurstSize,
|
|
1583
|
-
pauseMs: tuning.highVolumeWritePauseMs,
|
|
1584
|
-
flushDelayMs: tuning.highVolumeWriteFlushDelayMs,
|
|
1585
|
-
writeWithResponse: tuning.highVolumeWriteWithResponse,
|
|
1586
1613
|
});
|
|
1587
1614
|
}
|
|
1588
1615
|
try {
|
|
1589
|
-
|
|
1590
|
-
schemas: {
|
|
1591
|
-
protocolV1: this._messages,
|
|
1592
|
-
protocolV2: this._messagesV2,
|
|
1593
|
-
},
|
|
1594
|
-
router: transport.PROTOCOL_V2_CHANNEL_BLE_UART,
|
|
1595
|
-
writeFrame: (frame) => __awaiter(this, void 0, void 0, function* () {
|
|
1596
|
-
yield this.writeProtocolV2Frame(transport$1, frame, {
|
|
1597
|
-
highVolume: highVolumeWrite,
|
|
1598
|
-
});
|
|
1599
|
-
}),
|
|
1600
|
-
readFrame: () => __awaiter(this, void 0, void 0, function* () {
|
|
1601
|
-
const rxFrame = yield this.readProtocolV2Frame(uuid);
|
|
1602
|
-
if (!(rxFrame instanceof Uint8Array)) {
|
|
1603
|
-
throw new Error('Protocol V2 response is not Uint8Array');
|
|
1604
|
-
}
|
|
1605
|
-
return rxFrame;
|
|
1606
|
-
}),
|
|
1607
|
-
logger: Log,
|
|
1608
|
-
logPrefix: 'ProtocolV2 RN-BLE',
|
|
1609
|
-
createTimeoutError: (_messageName, timeout) => hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleTimeoutError, `BLE response timeout after ${timeout}ms for ${name}`),
|
|
1610
|
-
});
|
|
1611
|
-
const result = yield session.call(name, data, callOptions);
|
|
1612
|
-
completed = true;
|
|
1613
|
-
return result;
|
|
1616
|
+
return yield this.protocolV2Links.call(uuid, () => this.createProtocolV2Adapter(uuid), name, data, callOptions);
|
|
1614
1617
|
}
|
|
1615
1618
|
catch (e) {
|
|
1616
|
-
if (this.isActiveProtocolV2Call(uuid, callToken)) {
|
|
1617
|
-
(_c = this.protocolV2Assemblers.get(uuid)) === null || _c === void 0 ? void 0 : _c.reset();
|
|
1618
|
-
this.resetProtocolV2Frames(uuid);
|
|
1619
|
-
}
|
|
1620
1619
|
Log === null || Log === void 0 ? void 0 : Log.error('[ReactNativeBleTransport] Protocol V2 call error:', e);
|
|
1621
1620
|
throw e;
|
|
1622
1621
|
}
|
|
1623
|
-
finally {
|
|
1624
|
-
if (this.isActiveProtocolV2Call(uuid, callToken)) {
|
|
1625
|
-
if (!completed) {
|
|
1626
|
-
(_d = this.protocolV2Assemblers.get(uuid)) === null || _d === void 0 ? void 0 : _d.reset();
|
|
1627
|
-
}
|
|
1628
|
-
this.resetProtocolV2Frames(uuid);
|
|
1629
|
-
this.activeProtocolV2Call = null;
|
|
1630
|
-
}
|
|
1631
|
-
if (this.runPromise === runPromise) {
|
|
1632
|
-
this.runPromise = null;
|
|
1633
|
-
}
|
|
1634
|
-
}
|
|
1635
1622
|
});
|
|
1636
1623
|
}
|
|
1624
|
+
createProtocolV2Adapter(uuid) {
|
|
1625
|
+
var _a;
|
|
1626
|
+
const generation = (_a = this.monitorTokens.get(uuid)) !== null && _a !== void 0 ? _a : 0;
|
|
1627
|
+
const assertCurrentGeneration = () => {
|
|
1628
|
+
if (this.monitorTokens.get(uuid) !== generation) {
|
|
1629
|
+
throw new Error(`Protocol V2 monitor generation changed for ${uuid}`);
|
|
1630
|
+
}
|
|
1631
|
+
};
|
|
1632
|
+
return {
|
|
1633
|
+
router: transport.PROTOCOL_V2_CHANNEL_BLE_UART,
|
|
1634
|
+
maxFrameBytes: transport.PROTOCOL_V2_BLE_FRAME_MAX_BYTES,
|
|
1635
|
+
generation,
|
|
1636
|
+
prepareCall: () => {
|
|
1637
|
+
var _a;
|
|
1638
|
+
assertCurrentGeneration();
|
|
1639
|
+
(_a = this.protocolV2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
|
|
1640
|
+
this.resetProtocolV2Frames(uuid);
|
|
1641
|
+
},
|
|
1642
|
+
writeFrame: (frame, context) => __awaiter(this, void 0, void 0, function* () {
|
|
1643
|
+
assertCurrentGeneration();
|
|
1644
|
+
const currentTransport = this.getCachedTransport(uuid);
|
|
1645
|
+
yield this.writeProtocolV2Frame(currentTransport, frame, context, assertCurrentGeneration);
|
|
1646
|
+
}),
|
|
1647
|
+
readFrame: () => __awaiter(this, void 0, void 0, function* () {
|
|
1648
|
+
assertCurrentGeneration();
|
|
1649
|
+
const rxFrame = yield this.readProtocolV2Frame(uuid);
|
|
1650
|
+
if (!(rxFrame instanceof Uint8Array)) {
|
|
1651
|
+
throw new Error('Protocol V2 response is not Uint8Array');
|
|
1652
|
+
}
|
|
1653
|
+
return rxFrame;
|
|
1654
|
+
}),
|
|
1655
|
+
reset: (reason) => {
|
|
1656
|
+
var _a;
|
|
1657
|
+
(_a = this.protocolV2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
|
|
1658
|
+
this.rejectProtocolV2Frames(uuid, new Error(reason));
|
|
1659
|
+
},
|
|
1660
|
+
logger: Log,
|
|
1661
|
+
logPrefix: 'ProtocolV2 RN-BLE',
|
|
1662
|
+
createTimeoutError: (messageName, timeout) => hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleTimeoutError, `BLE response timeout after ${timeout}ms for ${messageName}`),
|
|
1663
|
+
};
|
|
1664
|
+
}
|
|
1637
1665
|
getProtocolType(path) {
|
|
1638
1666
|
return this.deviceProtocol.get(path);
|
|
1639
1667
|
}
|