@onekeyfe/hd-transport-react-native 1.1.27-alpha.41 → 1.1.27-alpha.6
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/BleManager.d.ts.map +1 -1
- package/dist/BleTransport.d.ts +0 -2
- package/dist/BleTransport.d.ts.map +1 -1
- package/dist/constants.d.ts +0 -4
- package/dist/constants.d.ts.map +1 -1
- package/dist/index.d.ts +29 -56
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +346 -885
- package/dist/types.d.ts +0 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/BleManager.ts +14 -14
- package/src/BleTransport.ts +5 -9
- package/src/constants.ts +1 -25
- package/src/index.ts +326 -955
- package/src/types.ts +0 -3
- package/src/utils/validateNotify.ts +4 -4
- package/dist/bleStrategy.d.ts +0 -15
- package/dist/bleStrategy.d.ts.map +0 -1
- package/dist/logger.d.ts +0 -14
- package/dist/logger.d.ts.map +0 -1
- package/src/__tests__/bleStrategy.test.ts +0 -47
- package/src/bleStrategy.ts +0 -62
- package/src/logger.ts +0 -19
package/dist/index.js
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
-
|
|
5
3
|
var reactNative = require('react-native');
|
|
6
4
|
var buffer = require('buffer');
|
|
7
5
|
var reactNativeBlePlx = require('react-native-ble-plx');
|
|
8
6
|
var ByteBuffer = require('bytebuffer');
|
|
9
7
|
var transport = require('@onekeyfe/hd-transport');
|
|
10
8
|
var hdShared = require('@onekeyfe/hd-shared');
|
|
9
|
+
var hdCore = require('@onekeyfe/hd-core');
|
|
11
10
|
var BleUtils = require('@onekeyfe/react-native-ble-utils');
|
|
12
11
|
|
|
13
12
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
@@ -46,126 +45,44 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
|
|
|
46
45
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
47
46
|
};
|
|
48
47
|
|
|
49
|
-
|
|
50
|
-
const setBleLogger = (logger) => {
|
|
51
|
-
activeLogger = logger;
|
|
52
|
-
};
|
|
53
|
-
const bleLogger = {
|
|
54
|
-
debug: (...args) => { var _a; return (_a = activeLogger === null || activeLogger === void 0 ? void 0 : activeLogger.debug) === null || _a === void 0 ? void 0 : _a.call(activeLogger, ...args); },
|
|
55
|
-
error: (...args) => { var _a; return (_a = activeLogger === null || activeLogger === void 0 ? void 0 : activeLogger.error) === null || _a === void 0 ? void 0 : _a.call(activeLogger, ...args); },
|
|
56
|
-
warn: (...args) => { var _a; return (_a = activeLogger === null || activeLogger === void 0 ? void 0 : activeLogger.warn) === null || _a === void 0 ? void 0 : _a.call(activeLogger, ...args); },
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
const Logger = bleLogger;
|
|
48
|
+
const Logger = hdCore.getLogger(hdCore.LoggerNames.HdBleTransport);
|
|
60
49
|
const getConnectedDeviceIds = (serviceUuids) => BleUtils__default["default"].getConnectedPeripherals(serviceUuids);
|
|
61
50
|
const pairDevice = (macAddress) => BleUtils__default["default"].pairDevice(macAddress);
|
|
62
51
|
const onDeviceBondState = (bleMacAddress) => new Promise((resolve, reject) => {
|
|
63
52
|
let timeout;
|
|
64
|
-
|
|
65
|
-
const cleanup = () => {
|
|
53
|
+
const cleanup = (cleanupListener) => {
|
|
66
54
|
if (timeout) {
|
|
67
55
|
clearTimeout(timeout);
|
|
68
56
|
}
|
|
69
57
|
if (cleanupListener)
|
|
70
58
|
cleanupListener();
|
|
71
59
|
};
|
|
72
|
-
|
|
73
|
-
cleanup();
|
|
74
|
-
reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceNotBonded, 'device is not bonded'));
|
|
75
|
-
}, 60 * 1000);
|
|
76
|
-
cleanupListener = BleUtils__default["default"].onDeviceBondState(peripheral => {
|
|
60
|
+
const cleanupListener = BleUtils__default["default"].onDeviceBondState(peripheral => {
|
|
77
61
|
var _a;
|
|
78
62
|
if (((_a = peripheral.id) === null || _a === void 0 ? void 0 : _a.toLowerCase()) !== bleMacAddress.toLowerCase()) {
|
|
79
63
|
return;
|
|
80
64
|
}
|
|
81
65
|
const { bondState } = peripheral;
|
|
66
|
+
if (bondState.preState === 'BOND_NONE' && bondState.state === 'BOND_BONDING') {
|
|
67
|
+
timeout = setTimeout(() => {
|
|
68
|
+
cleanup(cleanupListener);
|
|
69
|
+
reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceNotBonded, 'device is not bonded'));
|
|
70
|
+
}, 60 * 1000);
|
|
71
|
+
}
|
|
82
72
|
const hasBonded = bondState.preState === 'BOND_BONDING' && bondState.state === 'BOND_BONDED';
|
|
83
73
|
const hasCanceled = bondState.preState === 'BOND_BONDING' && bondState.state === 'BOND_NONE';
|
|
84
74
|
Logger.debug('onDeviceBondState bondState:', bondState);
|
|
85
75
|
if (hasBonded) {
|
|
86
|
-
cleanup();
|
|
76
|
+
cleanup(cleanupListener);
|
|
87
77
|
resolve(peripheral);
|
|
88
78
|
}
|
|
89
79
|
else if (hasCanceled) {
|
|
90
|
-
cleanup();
|
|
80
|
+
cleanup(cleanupListener);
|
|
91
81
|
reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceBondedCanceled, 'bonding canceled'));
|
|
92
82
|
}
|
|
93
83
|
});
|
|
94
84
|
});
|
|
95
85
|
|
|
96
|
-
const IOS_PACKET_LENGTH = 128;
|
|
97
|
-
const ANDROID_PACKET_LENGTH = 192;
|
|
98
|
-
const ANDROID_DEFAULT_MTU = 23;
|
|
99
|
-
const ClassicServiceUUID = '00000001-0000-1000-8000-00805f9b34fb';
|
|
100
|
-
const OneKeyServices = {
|
|
101
|
-
classic: {
|
|
102
|
-
[ClassicServiceUUID]: {
|
|
103
|
-
serviceUuid: ClassicServiceUUID,
|
|
104
|
-
writeUuid: '00000002-0000-1000-8000-00805f9b34fb',
|
|
105
|
-
notifyUuid: '00000003-0000-1000-8000-00805f9b34fb',
|
|
106
|
-
},
|
|
107
|
-
},
|
|
108
|
-
};
|
|
109
|
-
const bluetoothServices = [];
|
|
110
|
-
for (const deviceType of Object.keys(OneKeyServices)) {
|
|
111
|
-
const services = OneKeyServices[deviceType];
|
|
112
|
-
bluetoothServices.push(...Object.keys(services));
|
|
113
|
-
}
|
|
114
|
-
const getBluetoothServiceUuids = () => bluetoothServices;
|
|
115
|
-
const getInfosForServiceUuid = (serviceUuid, deviceType) => {
|
|
116
|
-
var _a;
|
|
117
|
-
const services = OneKeyServices[deviceType];
|
|
118
|
-
if (!services) {
|
|
119
|
-
return null;
|
|
120
|
-
}
|
|
121
|
-
const normalizedServiceUuid = normalizeBleUuid(serviceUuid);
|
|
122
|
-
const service = (_a = services[serviceUuid]) !== null && _a !== void 0 ? _a : Object.values(services).find(item => normalizeBleUuid(item.serviceUuid) === normalizedServiceUuid);
|
|
123
|
-
if (!service) {
|
|
124
|
-
return null;
|
|
125
|
-
}
|
|
126
|
-
return service;
|
|
127
|
-
};
|
|
128
|
-
const normalizeBleUuid = (uuid) => (uuid !== null && uuid !== void 0 ? uuid : '').replace(/-/g, '').toLowerCase();
|
|
129
|
-
const getBleUuidKey = (uuid) => {
|
|
130
|
-
const normalized = normalizeBleUuid(uuid);
|
|
131
|
-
return normalized.length >= 8 ? normalized.substring(4, 8) : normalized;
|
|
132
|
-
};
|
|
133
|
-
const isSameBleUuid = (left, right) => {
|
|
134
|
-
const normalizedLeft = normalizeBleUuid(left);
|
|
135
|
-
const normalizedRight = normalizeBleUuid(right);
|
|
136
|
-
return (normalizedLeft === normalizedRight ||
|
|
137
|
-
(getBleUuidKey(left) !== '' && getBleUuidKey(left) === getBleUuidKey(right)));
|
|
138
|
-
};
|
|
139
|
-
|
|
140
|
-
function hasWritableCapability(characteristic) {
|
|
141
|
-
return !!(characteristic.isWritableWithResponse || characteristic.isWritableWithoutResponse);
|
|
142
|
-
}
|
|
143
|
-
function resolveBleWriteMode(characteristic, preferredMode = 'withoutResponse') {
|
|
144
|
-
if (preferredMode === 'withoutResponse' && characteristic.isWritableWithoutResponse) {
|
|
145
|
-
return 'withoutResponse';
|
|
146
|
-
}
|
|
147
|
-
if (preferredMode === 'withResponse' && characteristic.isWritableWithResponse) {
|
|
148
|
-
return 'withResponse';
|
|
149
|
-
}
|
|
150
|
-
if (characteristic.isWritableWithoutResponse) {
|
|
151
|
-
return 'withoutResponse';
|
|
152
|
-
}
|
|
153
|
-
if (characteristic.isWritableWithResponse) {
|
|
154
|
-
return 'withResponse';
|
|
155
|
-
}
|
|
156
|
-
return preferredMode;
|
|
157
|
-
}
|
|
158
|
-
function resolveProtocolV2PacketCapacity({ platform, iosPacketLength = IOS_PACKET_LENGTH, androidPacketLength = ANDROID_PACKET_LENGTH, mtu, }) {
|
|
159
|
-
if (platform === 'ios') {
|
|
160
|
-
return iosPacketLength;
|
|
161
|
-
}
|
|
162
|
-
if (platform === 'android') {
|
|
163
|
-
const payloadLength = Math.max((mtu !== null && mtu !== void 0 ? mtu : ANDROID_DEFAULT_MTU) - 3, 1);
|
|
164
|
-
return Math.min(androidPacketLength, payloadLength);
|
|
165
|
-
}
|
|
166
|
-
return androidPacketLength;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
86
|
const timer = process.env.NODE_ENV === 'development'
|
|
170
87
|
? {
|
|
171
88
|
timeout: (fn, ms) => {
|
|
@@ -209,27 +126,58 @@ const subscribeBleOn = (bleManager, ms = 1000) => new Promise((resolve, reject)
|
|
|
209
126
|
}, ms);
|
|
210
127
|
});
|
|
211
128
|
|
|
129
|
+
const IOS_PACKET_LENGTH = 128;
|
|
130
|
+
const ANDROID_PACKET_LENGTH = 192;
|
|
131
|
+
const ClassicServiceUUID = '00000001-0000-1000-8000-00805f9b34fb';
|
|
132
|
+
const OneKeyServices = {
|
|
133
|
+
classic: {
|
|
134
|
+
[ClassicServiceUUID]: {
|
|
135
|
+
serviceUuid: ClassicServiceUUID,
|
|
136
|
+
writeUuid: '00000002-0000-1000-8000-00805f9b34fb',
|
|
137
|
+
notifyUuid: '00000003-0000-1000-8000-00805f9b34fb',
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
const bluetoothServices = [];
|
|
142
|
+
for (const deviceType of Object.keys(OneKeyServices)) {
|
|
143
|
+
const services = OneKeyServices[deviceType];
|
|
144
|
+
bluetoothServices.push(...Object.keys(services));
|
|
145
|
+
}
|
|
146
|
+
const getBluetoothServiceUuids = () => bluetoothServices;
|
|
147
|
+
const getInfosForServiceUuid = (serviceUuid, deviceType) => {
|
|
148
|
+
const services = OneKeyServices[deviceType];
|
|
149
|
+
if (!services) {
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
const service = services[serviceUuid];
|
|
153
|
+
if (!service) {
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
156
|
+
return service;
|
|
157
|
+
};
|
|
158
|
+
|
|
212
159
|
const isHeaderChunk = (chunk) => {
|
|
213
160
|
if (chunk.length < 9)
|
|
214
161
|
return false;
|
|
215
162
|
const [MagicQuestionMark, sharp1, sharp2] = chunk;
|
|
216
|
-
if (String.fromCharCode(MagicQuestionMark) === String.fromCharCode(transport.
|
|
217
|
-
String.fromCharCode(sharp1) === String.fromCharCode(transport.
|
|
218
|
-
String.fromCharCode(sharp2) === String.fromCharCode(transport.
|
|
163
|
+
if (String.fromCharCode(MagicQuestionMark) === String.fromCharCode(transport.MESSAGE_TOP_CHAR) &&
|
|
164
|
+
String.fromCharCode(sharp1) === String.fromCharCode(transport.MESSAGE_HEADER_BYTE) &&
|
|
165
|
+
String.fromCharCode(sharp2) === String.fromCharCode(transport.MESSAGE_HEADER_BYTE)) {
|
|
219
166
|
return true;
|
|
220
167
|
}
|
|
221
168
|
return false;
|
|
222
169
|
};
|
|
223
170
|
|
|
224
|
-
const Log$1 =
|
|
171
|
+
const Log$1 = hdCore.getLogger(hdCore.LoggerNames.HdBleTransport);
|
|
225
172
|
class BleTransport {
|
|
226
173
|
constructor(device, writeCharacteristic, notifyCharacteristic) {
|
|
227
174
|
this.name = 'ReactNativeBleTransport';
|
|
228
|
-
this.mtuSize =
|
|
175
|
+
this.mtuSize = 20;
|
|
229
176
|
this.id = device.id;
|
|
230
177
|
this.device = device;
|
|
231
178
|
this.writeCharacteristic = writeCharacteristic;
|
|
232
179
|
this.notifyCharacteristic = notifyCharacteristic;
|
|
180
|
+
console.log(`BleTransport(${String(this.id)}) new instance`);
|
|
233
181
|
}
|
|
234
182
|
writeWithRetry(data, retryCount = BleTransport.MAX_RETRIES) {
|
|
235
183
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -239,7 +187,7 @@ class BleTransport {
|
|
|
239
187
|
catch (error) {
|
|
240
188
|
Log$1 === null || Log$1 === void 0 ? void 0 : Log$1.debug(`Write retry attempt ${BleTransport.MAX_RETRIES - retryCount + 1}, error: ${error}`);
|
|
241
189
|
if (retryCount > 0) {
|
|
242
|
-
yield
|
|
190
|
+
yield hdCore.wait(BleTransport.RETRY_DELAY);
|
|
243
191
|
if (error.errorCode === reactNativeBlePlx.BleErrorCode.DeviceDisconnected ||
|
|
244
192
|
error.errorCode === reactNativeBlePlx.BleErrorCode.CharacteristicNotFound) {
|
|
245
193
|
try {
|
|
@@ -263,101 +211,52 @@ class BleTransport {
|
|
|
263
211
|
BleTransport.MAX_RETRIES = 5;
|
|
264
212
|
BleTransport.RETRY_DELAY = 2000;
|
|
265
213
|
|
|
266
|
-
const { check,
|
|
267
|
-
const Log =
|
|
214
|
+
const { check, buildBuffers, receiveOne, parseConfigure } = transport__default["default"];
|
|
215
|
+
const Log = hdCore.getLogger(hdCore.LoggerNames.HdBleTransport);
|
|
268
216
|
const transportCache = {};
|
|
269
|
-
const
|
|
270
|
-
const
|
|
271
|
-
const
|
|
272
|
-
const
|
|
273
|
-
const
|
|
274
|
-
const
|
|
275
|
-
const
|
|
276
|
-
const
|
|
277
|
-
const HIGH_VOLUME_WRITE_FLUSH_DELAY_MS = reactNative.Platform.OS === 'ios' ? 20 : 8;
|
|
217
|
+
const FIRMWARE_UPLOAD_WRITE_BURST_SIZE = reactNative.Platform.OS === 'ios' ? 4 : 5;
|
|
218
|
+
const FIRMWARE_UPLOAD_WRITE_PAUSE_MS = reactNative.Platform.OS === 'ios' ? 8 : 10;
|
|
219
|
+
const FIRMWARE_UPLOAD_WRITE_FLUSH_DELAY_MS = reactNative.Platform.OS === 'ios' ? 24 : 30;
|
|
220
|
+
const FIRMWARE_UPLOAD_WRITE_MAX_RETRIES = 8;
|
|
221
|
+
const FIRMWARE_UPLOAD_RECONNECT_RETRY_DELAY_MS = 2000;
|
|
222
|
+
const ANDROID_FIRMWARE_UPLOAD_PACKET_LENGTH = 192;
|
|
223
|
+
const FIRMWARE_UPLOAD_WRITE_PACKET_CAPACITY = reactNative.Platform.OS === 'ios' ? IOS_PACKET_LENGTH : ANDROID_FIRMWARE_UPLOAD_PACKET_LENGTH;
|
|
224
|
+
const ANDROID_GATT_CONGESTED_STATUS = 143;
|
|
278
225
|
const delay = (ms) => new Promise(resolve => {
|
|
279
226
|
setTimeout(resolve, ms);
|
|
280
227
|
});
|
|
281
|
-
const
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
228
|
+
const getFirmwareUploadWriteRetryType = (error) => {
|
|
229
|
+
if (!error || typeof error !== 'object')
|
|
230
|
+
return null;
|
|
231
|
+
const bleWriteError = error;
|
|
232
|
+
if (bleWriteError.errorCode === reactNativeBlePlx.BleErrorCode.DeviceDisconnected ||
|
|
233
|
+
bleWriteError.errorCode === reactNativeBlePlx.BleErrorCode.CharacteristicNotFound) {
|
|
234
|
+
return 'reconnectable';
|
|
235
|
+
}
|
|
236
|
+
if (bleWriteError.androidErrorCode === ANDROID_GATT_CONGESTED_STATUS ||
|
|
237
|
+
bleWriteError.status === ANDROID_GATT_CONGESTED_STATUS) {
|
|
238
|
+
return 'congested';
|
|
239
|
+
}
|
|
240
|
+
const text = [bleWriteError.reason, bleWriteError.message, bleWriteError.name]
|
|
241
|
+
.filter(value => typeof value === 'string')
|
|
242
|
+
.join(' ');
|
|
243
|
+
return /GATT_CONGESTED|status\s*[:=]?\s*143/.test(text) ? 'congested' : null;
|
|
295
244
|
};
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
iosPacketLength: normalizePositiveInteger(tuning.iosPacketLength, protocolV2BleTuning.iosPacketLength),
|
|
300
|
-
androidPacketLength: normalizePositiveInteger(tuning.androidPacketLength, protocolV2BleTuning.androidPacketLength),
|
|
301
|
-
highVolumeWriteBurstSize: normalizePositiveInteger(tuning.highVolumeWriteBurstSize, protocolV2BleTuning.highVolumeWriteBurstSize),
|
|
302
|
-
highVolumeWritePauseMs: normalizePositiveInteger(tuning.highVolumeWritePauseMs, protocolV2BleTuning.highVolumeWritePauseMs),
|
|
303
|
-
highVolumeWriteFlushDelayMs: normalizePositiveInteger(tuning.highVolumeWriteFlushDelayMs, protocolV2BleTuning.highVolumeWriteFlushDelayMs),
|
|
304
|
-
highVolumeWriteWithResponse: (_a = tuning.highVolumeWriteWithResponse) !== null && _a !== void 0 ? _a : protocolV2BleTuning.highVolumeWriteWithResponse,
|
|
305
|
-
};
|
|
306
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V2 BLE tuning configured:', protocolV2BleTuning);
|
|
307
|
-
}
|
|
308
|
-
function resetProtocolV2BleTuning() {
|
|
309
|
-
protocolV2BleTuning = Object.assign({}, DEFAULT_PROTOCOL_V2_BLE_TUNING);
|
|
310
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V2 BLE tuning reset:', protocolV2BleTuning);
|
|
311
|
-
}
|
|
312
|
-
function getProtocolV2BleTuning() {
|
|
313
|
-
return Object.assign({}, protocolV2BleTuning);
|
|
314
|
-
}
|
|
315
|
-
function inferProtocolHintFromDeviceName(name) {
|
|
316
|
-
return /\bpro\s*2\b/i.test(name !== null && name !== void 0 ? name : '') ? 'V2' : undefined;
|
|
317
|
-
}
|
|
318
|
-
function getDeviceDisplayName(device) {
|
|
319
|
-
return (device === null || device === void 0 ? void 0 : device.name) || (device === null || device === void 0 ? void 0 : device.localName) || null;
|
|
320
|
-
}
|
|
321
|
-
function isGenericBleService(uuid) {
|
|
322
|
-
return ['1800', '1801', '180a'].includes(getBleUuidKey(uuid));
|
|
323
|
-
}
|
|
324
|
-
function hasKnownOneKeyService(device) {
|
|
325
|
-
var _a;
|
|
326
|
-
return ((_a = device === null || device === void 0 ? void 0 : device.serviceUUIDs) !== null && _a !== void 0 ? _a : []).some(serviceUuid => getInfosForServiceUuid(serviceUuid, 'classic'));
|
|
327
|
-
}
|
|
328
|
-
const ANDROID_REQUEST_MTU = 256;
|
|
329
|
-
const connectOptions = {
|
|
330
|
-
requestMTU: ANDROID_REQUEST_MTU,
|
|
245
|
+
const resolveFirmwareUploadRetryDelay = (attempt, baseDelayMs = 200, maxDelayMs = 1200) => Math.min(baseDelayMs * Math.pow(2, attempt), maxDelayMs);
|
|
246
|
+
let connectOptions = {
|
|
247
|
+
requestMTU: 256,
|
|
331
248
|
timeout: 3000,
|
|
332
249
|
refreshGatt: 'OnConnected',
|
|
333
250
|
};
|
|
334
251
|
const tryToGetConfiguration = (device) => {
|
|
335
252
|
if (!device || !device.serviceUUIDs)
|
|
336
253
|
return null;
|
|
337
|
-
const serviceUUID = device.serviceUUIDs
|
|
338
|
-
if (!serviceUUID)
|
|
339
|
-
return null;
|
|
254
|
+
const [serviceUUID] = device.serviceUUIDs;
|
|
340
255
|
const infos = getInfosForServiceUuid(serviceUUID, 'classic');
|
|
341
256
|
if (!infos)
|
|
342
257
|
return null;
|
|
343
258
|
return infos;
|
|
344
259
|
};
|
|
345
|
-
const requestAndroidMtu = (device) => __awaiter(void 0, void 0, void 0, function* () {
|
|
346
|
-
if (reactNative.Platform.OS !== 'android')
|
|
347
|
-
return device;
|
|
348
|
-
try {
|
|
349
|
-
const mtuDevice = yield device.requestMTU(ANDROID_REQUEST_MTU);
|
|
350
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Android MTU requested:', {
|
|
351
|
-
requested: ANDROID_REQUEST_MTU,
|
|
352
|
-
mtu: mtuDevice.mtu,
|
|
353
|
-
});
|
|
354
|
-
return mtuDevice;
|
|
355
|
-
}
|
|
356
|
-
catch (error) {
|
|
357
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Android MTU request failed:', error);
|
|
358
|
-
return device;
|
|
359
|
-
}
|
|
360
|
-
});
|
|
361
260
|
function remapError(error) {
|
|
362
261
|
var _a;
|
|
363
262
|
if (error instanceof reactNativeBlePlx.BleError) {
|
|
@@ -382,21 +281,12 @@ class ReactNativeBleTransport {
|
|
|
382
281
|
this.name = 'ReactNativeBleTransport';
|
|
383
282
|
this.configured = false;
|
|
384
283
|
this.stopped = false;
|
|
385
|
-
this.scanTimeout =
|
|
284
|
+
this.scanTimeout = 3000;
|
|
386
285
|
this.runPromise = null;
|
|
387
|
-
this.
|
|
388
|
-
this.
|
|
389
|
-
this.protocolV2Assemblers = new Map();
|
|
390
|
-
this.protocolV2FrameQueues = new Map();
|
|
391
|
-
this.protocolV2FramePromises = new Map();
|
|
392
|
-
this.activeProtocolV2Call = null;
|
|
393
|
-
this.nextProtocolV2CallToken = 1;
|
|
394
|
-
this.monitorTokens = new Map();
|
|
395
|
-
this.nextMonitorToken = 1;
|
|
396
|
-
this.scanTimeout = (_a = options.scanTimeout) !== null && _a !== void 0 ? _a : DEVICE_SCAN_TIMEOUT_MS;
|
|
286
|
+
this.firmwareUploadWriteRecoveryIds = new Set();
|
|
287
|
+
this.scanTimeout = (_a = options.scanTimeout) !== null && _a !== void 0 ? _a : 3000;
|
|
397
288
|
}
|
|
398
|
-
init(
|
|
399
|
-
setBleLogger(logger);
|
|
289
|
+
init(_logger, emitter) {
|
|
400
290
|
this.emitter = emitter;
|
|
401
291
|
}
|
|
402
292
|
configure(signedData) {
|
|
@@ -404,10 +294,6 @@ class ReactNativeBleTransport {
|
|
|
404
294
|
this.configured = true;
|
|
405
295
|
this._messages = messages;
|
|
406
296
|
}
|
|
407
|
-
configureProtocolV2(signedData) {
|
|
408
|
-
this._messagesV2 = parseConfigure(signedData);
|
|
409
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V2 schema configured');
|
|
410
|
-
}
|
|
411
297
|
listen() {
|
|
412
298
|
}
|
|
413
299
|
getPlxManager() {
|
|
@@ -416,6 +302,134 @@ class ReactNativeBleTransport {
|
|
|
416
302
|
this.blePlxManager = new reactNativeBlePlx.BleManager();
|
|
417
303
|
return Promise.resolve(this.blePlxManager);
|
|
418
304
|
}
|
|
305
|
+
resolveCharacteristics(device) {
|
|
306
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
307
|
+
yield device.discoverAllServicesAndCharacteristics();
|
|
308
|
+
let infos = tryToGetConfiguration(device);
|
|
309
|
+
let characteristics;
|
|
310
|
+
if (!infos) {
|
|
311
|
+
for (const serviceUuid of getBluetoothServiceUuids()) {
|
|
312
|
+
try {
|
|
313
|
+
characteristics = yield device.characteristicsForService(serviceUuid);
|
|
314
|
+
infos = getInfosForServiceUuid(serviceUuid, 'classic');
|
|
315
|
+
break;
|
|
316
|
+
}
|
|
317
|
+
catch (e) {
|
|
318
|
+
Log === null || Log === void 0 ? void 0 : Log.error(e);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
if (!infos) {
|
|
323
|
+
try {
|
|
324
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('cancel connection when service not found');
|
|
325
|
+
yield device.cancelConnection();
|
|
326
|
+
}
|
|
327
|
+
catch (e) {
|
|
328
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('cancel connection error when service not found: ', e.message || e.reason);
|
|
329
|
+
}
|
|
330
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleServiceNotFound);
|
|
331
|
+
}
|
|
332
|
+
const { serviceUuid, writeUuid, notifyUuid } = infos;
|
|
333
|
+
if (!characteristics) {
|
|
334
|
+
characteristics = yield device.characteristicsForService(serviceUuid);
|
|
335
|
+
}
|
|
336
|
+
if (!characteristics) {
|
|
337
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleCharacteristicNotFound);
|
|
338
|
+
}
|
|
339
|
+
let writeCharacteristic;
|
|
340
|
+
let notifyCharacteristic;
|
|
341
|
+
for (const c of characteristics) {
|
|
342
|
+
if (c.uuid === writeUuid) {
|
|
343
|
+
writeCharacteristic = c;
|
|
344
|
+
}
|
|
345
|
+
else if (c.uuid === notifyUuid) {
|
|
346
|
+
notifyCharacteristic = c;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
if (!writeCharacteristic) {
|
|
350
|
+
throw hdShared.ERRORS.TypedError('BLECharacteristicNotFound: write characteristic not found');
|
|
351
|
+
}
|
|
352
|
+
if (!notifyCharacteristic) {
|
|
353
|
+
throw hdShared.ERRORS.TypedError('BLECharacteristicNotFound: notify characteristic not found');
|
|
354
|
+
}
|
|
355
|
+
if (!writeCharacteristic.isWritableWithResponse) {
|
|
356
|
+
throw hdShared.ERRORS.TypedError('BLECharacteristicNotWritable: write characteristic not writable');
|
|
357
|
+
}
|
|
358
|
+
if (!notifyCharacteristic.isNotifiable) {
|
|
359
|
+
throw hdShared.ERRORS.TypedError('BLECharacteristicNotNotifiable: notify characteristic not notifiable');
|
|
360
|
+
}
|
|
361
|
+
return {
|
|
362
|
+
writeCharacteristic,
|
|
363
|
+
notifyCharacteristic,
|
|
364
|
+
};
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
attachDisconnectSubscription(transport, device, uuid) {
|
|
368
|
+
var _a;
|
|
369
|
+
(_a = transport.disconnectSubscription) === null || _a === void 0 ? void 0 : _a.remove();
|
|
370
|
+
transport.disconnectSubscription = device.onDisconnected(() => {
|
|
371
|
+
var _a;
|
|
372
|
+
if (this.firmwareUploadWriteRecoveryIds.has(uuid)) {
|
|
373
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('device disconnect ignored during FirmwareUpload write recovery: ', uuid);
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
try {
|
|
377
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('device disconnect: ', device === null || device === void 0 ? void 0 : device.id);
|
|
378
|
+
(_a = this.emitter) === null || _a === void 0 ? void 0 : _a.emit('device-disconnect', {
|
|
379
|
+
name: device === null || device === void 0 ? void 0 : device.name,
|
|
380
|
+
id: device === null || device === void 0 ? void 0 : device.id,
|
|
381
|
+
connectId: device === null || device === void 0 ? void 0 : device.id,
|
|
382
|
+
});
|
|
383
|
+
if (this.runPromise) {
|
|
384
|
+
this.runPromise.reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleConnectedError));
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
catch (e) {
|
|
388
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('device disconnect error: ', e);
|
|
389
|
+
}
|
|
390
|
+
finally {
|
|
391
|
+
this.release(uuid);
|
|
392
|
+
}
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
reconnectFirmwareUploadTransport(uuid, transport) {
|
|
396
|
+
var _a, _b;
|
|
397
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
398
|
+
this.firmwareUploadWriteRecoveryIds.add(uuid);
|
|
399
|
+
try {
|
|
400
|
+
(_a = transport.disconnectSubscription) === null || _a === void 0 ? void 0 : _a.remove();
|
|
401
|
+
transport.disconnectSubscription = undefined;
|
|
402
|
+
(_b = transport.notifySubscription) === null || _b === void 0 ? void 0 : _b.remove();
|
|
403
|
+
transport.notifySubscription = undefined;
|
|
404
|
+
let { device } = transport;
|
|
405
|
+
const isConnected = yield device.isConnected().catch(() => false);
|
|
406
|
+
if (!isConnected) {
|
|
407
|
+
try {
|
|
408
|
+
device = yield device.connect(connectOptions);
|
|
409
|
+
}
|
|
410
|
+
catch (e) {
|
|
411
|
+
if (e.errorCode === reactNativeBlePlx.BleErrorCode.DeviceMTUChangeFailed ||
|
|
412
|
+
e.errorCode === reactNativeBlePlx.BleErrorCode.OperationCancelled) {
|
|
413
|
+
connectOptions = {};
|
|
414
|
+
device = yield device.connect();
|
|
415
|
+
}
|
|
416
|
+
else if (e.errorCode !== reactNativeBlePlx.BleErrorCode.DeviceAlreadyConnected) {
|
|
417
|
+
throw e;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
const { writeCharacteristic, notifyCharacteristic } = yield this.resolveCharacteristics(device);
|
|
422
|
+
transport.device = device;
|
|
423
|
+
transport.writeCharacteristic = writeCharacteristic;
|
|
424
|
+
transport.notifyCharacteristic = notifyCharacteristic;
|
|
425
|
+
transport.notifySubscription = this._monitorCharacteristic(notifyCharacteristic, uuid);
|
|
426
|
+
this.attachDisconnectSubscription(transport, device, uuid);
|
|
427
|
+
}
|
|
428
|
+
finally {
|
|
429
|
+
this.firmwareUploadWriteRecoveryIds.delete(uuid);
|
|
430
|
+
}
|
|
431
|
+
});
|
|
432
|
+
}
|
|
419
433
|
enumerate() {
|
|
420
434
|
return __awaiter(this, void 0, void 0, function* () {
|
|
421
435
|
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -443,10 +457,9 @@ class ReactNativeBleTransport {
|
|
|
443
457
|
}
|
|
444
458
|
}
|
|
445
459
|
blePlxManager.startDeviceScan(null, {
|
|
446
|
-
allowDuplicates: true,
|
|
447
460
|
scanMode: reactNativeBlePlx.ScanMode.LowLatency,
|
|
448
461
|
}, (error, device) => {
|
|
449
|
-
var _a, _b
|
|
462
|
+
var _a, _b;
|
|
450
463
|
if (error) {
|
|
451
464
|
Log === null || Log === void 0 ? void 0 : Log.debug('ble scan manager: ', blePlxManager);
|
|
452
465
|
Log === null || Log === void 0 ? void 0 : Log.debug('ble scan error: ', error);
|
|
@@ -467,35 +480,13 @@ class ReactNativeBleTransport {
|
|
|
467
480
|
}
|
|
468
481
|
return;
|
|
469
482
|
}
|
|
470
|
-
|
|
471
|
-
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) ||
|
|
472
|
-
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) ||
|
|
473
|
-
hasKnownOneKeyService(device);
|
|
474
|
-
const shouldTraceCandidate = !!displayName && /onekey|bixinkey|pro\s*2|pro\b|touch|^k\d|^t\d/i.test(displayName);
|
|
475
|
-
if (shouldTraceCandidate) {
|
|
476
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] scan candidate', {
|
|
477
|
-
name: device === null || device === void 0 ? void 0 : device.name,
|
|
478
|
-
localName: device === null || device === void 0 ? void 0 : device.localName,
|
|
479
|
-
id: device === null || device === void 0 ? void 0 : device.id,
|
|
480
|
-
serviceUUIDs: device === null || device === void 0 ? void 0 : device.serviceUUIDs,
|
|
481
|
-
accepted: isOneKey,
|
|
482
|
-
});
|
|
483
|
-
}
|
|
484
|
-
if (isOneKey) {
|
|
483
|
+
if (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)) {
|
|
485
484
|
Log === null || Log === void 0 ? void 0 : Log.debug('search device start ======================');
|
|
486
|
-
const { name, localName, id
|
|
487
|
-
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 : ''}
|
|
485
|
+
const { name, localName, id } = device !== null && device !== void 0 ? device : {};
|
|
486
|
+
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 : ''}`);
|
|
488
487
|
addDevice(device);
|
|
489
488
|
Log === null || Log === void 0 ? void 0 : Log.debug('search device end ======================\n');
|
|
490
489
|
}
|
|
491
|
-
else if (displayName && /\bpro\s*2\b/i.test(displayName)) {
|
|
492
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Pro2-like BLE device was not accepted:', {
|
|
493
|
-
name: device === null || device === void 0 ? void 0 : device.name,
|
|
494
|
-
localName: device === null || device === void 0 ? void 0 : device.localName,
|
|
495
|
-
id: device === null || device === void 0 ? void 0 : device.id,
|
|
496
|
-
serviceUUIDs: device === null || device === void 0 ? void 0 : device.serviceUUIDs,
|
|
497
|
-
});
|
|
498
|
-
}
|
|
499
490
|
});
|
|
500
491
|
getConnectedDeviceIds(getBluetoothServiceUuids()).then(devices => {
|
|
501
492
|
for (const device of devices) {
|
|
@@ -504,14 +495,8 @@ class ReactNativeBleTransport {
|
|
|
504
495
|
}
|
|
505
496
|
});
|
|
506
497
|
const addDevice = (device) => {
|
|
507
|
-
var _a;
|
|
508
498
|
if (deviceList.every(d => d.id !== device.id)) {
|
|
509
|
-
|
|
510
|
-
const protocolHint = inferProtocolHintFromDeviceName(displayName);
|
|
511
|
-
if (protocolHint) {
|
|
512
|
-
this.deviceProtocolHints.set(device.id, protocolHint);
|
|
513
|
-
}
|
|
514
|
-
deviceList.push(Object.assign(Object.assign({}, device), { name: displayName, commType: 'ble' }));
|
|
499
|
+
deviceList.push(Object.assign(Object.assign({}, device), { commType: 'ble' }));
|
|
515
500
|
}
|
|
516
501
|
};
|
|
517
502
|
timer.timeout(() => {
|
|
@@ -522,32 +507,19 @@ class ReactNativeBleTransport {
|
|
|
522
507
|
});
|
|
523
508
|
}
|
|
524
509
|
acquire(input) {
|
|
525
|
-
var _a
|
|
510
|
+
var _a;
|
|
526
511
|
return __awaiter(this, void 0, void 0, function* () {
|
|
527
|
-
const { uuid, forceCleanRunPromise
|
|
512
|
+
const { uuid, forceCleanRunPromise } = input;
|
|
528
513
|
if (!uuid) {
|
|
529
514
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleRequiredUUID);
|
|
530
515
|
}
|
|
531
|
-
const cachedTransport = transportCache[uuid];
|
|
532
|
-
if (cachedTransport) {
|
|
533
|
-
const cachedProtocol = this.deviceProtocol.get(uuid);
|
|
534
|
-
const isCachedDeviceConnected = yield cachedTransport.device.isConnected().catch(() => false);
|
|
535
|
-
if (isCachedDeviceConnected &&
|
|
536
|
-
cachedProtocol &&
|
|
537
|
-
(!expectedProtocol || cachedProtocol === expectedProtocol)) {
|
|
538
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] reuse cached BLE transport:', uuid, cachedProtocol);
|
|
539
|
-
return { uuid, protocolType: cachedProtocol };
|
|
540
|
-
}
|
|
541
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('transport not reusable, will release: ', uuid);
|
|
542
|
-
yield this.release(uuid, true);
|
|
543
|
-
}
|
|
544
516
|
let device = null;
|
|
517
|
+
if (transportCache[uuid]) {
|
|
518
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('transport not be released, will release: ', uuid);
|
|
519
|
+
yield this.release(uuid);
|
|
520
|
+
}
|
|
545
521
|
if (forceCleanRunPromise && this.runPromise) {
|
|
546
|
-
|
|
547
|
-
this.runPromise.reject(error);
|
|
548
|
-
this.rejectAllProtocolV2Frames(error);
|
|
549
|
-
this.runPromise = null;
|
|
550
|
-
this.activeProtocolV2Call = null;
|
|
522
|
+
this.runPromise.reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleForceCleanRunPromise));
|
|
551
523
|
Log === null || Log === void 0 ? void 0 : Log.debug('Force clean Bluetooth run promise, forceCleanRunPromise: ', forceCleanRunPromise);
|
|
552
524
|
}
|
|
553
525
|
const blePlxManager = yield this.getPlxManager();
|
|
@@ -563,9 +535,6 @@ class ReactNativeBleTransport {
|
|
|
563
535
|
if (bondState.bonding) {
|
|
564
536
|
yield onDeviceBondState(uuid);
|
|
565
537
|
}
|
|
566
|
-
else if (!bondState.bonded) {
|
|
567
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceNotBonded, 'device is not bonded');
|
|
568
|
-
}
|
|
569
538
|
}
|
|
570
539
|
if (!device) {
|
|
571
540
|
const devices = yield blePlxManager.devices([uuid]);
|
|
@@ -586,6 +555,7 @@ class ReactNativeBleTransport {
|
|
|
586
555
|
Log === null || Log === void 0 ? void 0 : Log.debug('try to connect to device has error: ', e);
|
|
587
556
|
if (e.errorCode === reactNativeBlePlx.BleErrorCode.DeviceMTUChangeFailed ||
|
|
588
557
|
e.errorCode === reactNativeBlePlx.BleErrorCode.OperationCancelled) {
|
|
558
|
+
connectOptions = {};
|
|
589
559
|
Log === null || Log === void 0 ? void 0 : Log.debug('first try to reconnect without params');
|
|
590
560
|
device = yield blePlxManager.connectToDevice(uuid);
|
|
591
561
|
}
|
|
@@ -604,22 +574,23 @@ class ReactNativeBleTransport {
|
|
|
604
574
|
if (!(yield device.isConnected())) {
|
|
605
575
|
Log === null || Log === void 0 ? void 0 : Log.debug('not connected, try to connect to device: ', uuid);
|
|
606
576
|
try {
|
|
607
|
-
|
|
577
|
+
yield device.connect(connectOptions);
|
|
608
578
|
}
|
|
609
579
|
catch (e) {
|
|
610
580
|
Log === null || Log === void 0 ? void 0 : Log.debug('not connected, try to connect to device has error: ', e);
|
|
611
581
|
if (e.errorCode === reactNativeBlePlx.BleErrorCode.DeviceMTUChangeFailed ||
|
|
612
582
|
e.errorCode === reactNativeBlePlx.BleErrorCode.OperationCancelled) {
|
|
583
|
+
connectOptions = {};
|
|
613
584
|
Log === null || Log === void 0 ? void 0 : Log.debug('second try to reconnect without params');
|
|
614
585
|
try {
|
|
615
|
-
|
|
586
|
+
yield device.connect();
|
|
616
587
|
}
|
|
617
588
|
catch (e) {
|
|
618
589
|
Log === null || Log === void 0 ? void 0 : Log.debug('last try to reconnect error: ', e);
|
|
619
590
|
if (e.errorCode === reactNativeBlePlx.BleErrorCode.OperationCancelled) {
|
|
620
591
|
Log === null || Log === void 0 ? void 0 : Log.debug('last try to reconnect');
|
|
621
592
|
yield device.cancelConnection();
|
|
622
|
-
|
|
593
|
+
yield device.connect();
|
|
623
594
|
}
|
|
624
595
|
}
|
|
625
596
|
}
|
|
@@ -628,153 +599,29 @@ class ReactNativeBleTransport {
|
|
|
628
599
|
}
|
|
629
600
|
}
|
|
630
601
|
}
|
|
631
|
-
|
|
632
|
-
yield
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
for (const serviceUuid of getBluetoothServiceUuids()) {
|
|
638
|
-
try {
|
|
639
|
-
characteristics = yield device.characteristicsForService(serviceUuid);
|
|
640
|
-
infos = getInfosForServiceUuid(serviceUuid, 'classic');
|
|
641
|
-
break;
|
|
642
|
-
}
|
|
643
|
-
catch (e) {
|
|
644
|
-
Log === null || Log === void 0 ? void 0 : Log.error(e);
|
|
645
|
-
}
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
if (!infos) {
|
|
649
|
-
const services = yield device.services();
|
|
650
|
-
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));
|
|
651
|
-
const knownService = services.find(service => getInfosForServiceUuid(service.uuid, 'classic'));
|
|
652
|
-
const fallbackService = (_a = knownService !== null && knownService !== void 0 ? knownService : services.find(service => !isGenericBleService(service.uuid))) !== null && _a !== void 0 ? _a : services[0];
|
|
653
|
-
if (fallbackService) {
|
|
654
|
-
fallbackServiceUuid = fallbackService.uuid;
|
|
655
|
-
characteristics = yield device.characteristicsForService(fallbackService.uuid);
|
|
656
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Using fallback BLE service:', fallbackService.uuid);
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
if (!infos) {
|
|
660
|
-
if (!fallbackServiceUuid) {
|
|
661
|
-
try {
|
|
662
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('cancel connection when service not found');
|
|
663
|
-
yield device.cancelConnection();
|
|
664
|
-
}
|
|
665
|
-
catch (e) {
|
|
666
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('cancel connection error when service not found: ', e.message || e.reason);
|
|
667
|
-
}
|
|
668
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleServiceNotFound);
|
|
669
|
-
}
|
|
670
|
-
}
|
|
671
|
-
const serviceUuid = (_b = infos === null || infos === void 0 ? void 0 : infos.serviceUuid) !== null && _b !== void 0 ? _b : fallbackServiceUuid;
|
|
672
|
-
const writeUuid = (_c = infos === null || infos === void 0 ? void 0 : infos.writeUuid) !== null && _c !== void 0 ? _c : '00000002-0000-1000-8000-00805f9b34fb';
|
|
673
|
-
const notifyUuid = (_d = infos === null || infos === void 0 ? void 0 : infos.notifyUuid) !== null && _d !== void 0 ? _d : '00000003-0000-1000-8000-00805f9b34fb';
|
|
674
|
-
if (!serviceUuid) {
|
|
675
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleServiceNotFound);
|
|
676
|
-
}
|
|
677
|
-
if (!characteristics) {
|
|
678
|
-
characteristics = yield device.characteristicsForService(serviceUuid);
|
|
679
|
-
}
|
|
680
|
-
if (!characteristics) {
|
|
681
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleCharacteristicNotFound);
|
|
682
|
-
}
|
|
683
|
-
let writeCharacteristic;
|
|
684
|
-
let notifyCharacteristic;
|
|
685
|
-
for (const c of characteristics) {
|
|
686
|
-
if (isSameBleUuid(c.uuid, writeUuid)) {
|
|
687
|
-
writeCharacteristic = c;
|
|
688
|
-
}
|
|
689
|
-
else if (isSameBleUuid(c.uuid, notifyUuid)) {
|
|
690
|
-
notifyCharacteristic = c;
|
|
691
|
-
}
|
|
692
|
-
}
|
|
693
|
-
if (!writeCharacteristic) {
|
|
694
|
-
throw hdShared.ERRORS.TypedError('BLECharacteristicNotFound: write characteristic not found');
|
|
695
|
-
}
|
|
696
|
-
if (!notifyCharacteristic) {
|
|
697
|
-
throw hdShared.ERRORS.TypedError('BLECharacteristicNotFound: notify characteristic not found');
|
|
698
|
-
}
|
|
699
|
-
if (!hasWritableCapability(writeCharacteristic)) {
|
|
700
|
-
throw hdShared.ERRORS.TypedError('BLECharacteristicNotWritable: write characteristic not writable');
|
|
701
|
-
}
|
|
702
|
-
if (!notifyCharacteristic.isNotifiable) {
|
|
703
|
-
throw hdShared.ERRORS.TypedError('BLECharacteristicNotNotifiable: notify characteristic not notifiable');
|
|
704
|
-
}
|
|
705
|
-
const protocolHint = expectedProtocol
|
|
706
|
-
? undefined
|
|
707
|
-
: (_e = this.deviceProtocolHints.get(uuid)) !== null && _e !== void 0 ? _e : inferProtocolHintFromDeviceName(getDeviceDisplayName(device));
|
|
708
|
-
yield this.release(uuid, true);
|
|
709
|
-
if (protocolHint) {
|
|
710
|
-
this.deviceProtocolHints.set(uuid, protocolHint);
|
|
711
|
-
}
|
|
712
|
-
const transport$1 = new BleTransport(device, writeCharacteristic, notifyCharacteristic);
|
|
713
|
-
if (reactNative.Platform.OS === 'android') {
|
|
714
|
-
transport$1.mtuSize = typeof device.mtu === 'number' ? device.mtu : transport$1.mtuSize;
|
|
715
|
-
}
|
|
716
|
-
const monitorToken = this.nextMonitorToken;
|
|
717
|
-
this.nextMonitorToken += 1;
|
|
718
|
-
const notifyTransactionId = `${uuid}:notify:${monitorToken}`;
|
|
719
|
-
transport$1.monitorToken = monitorToken;
|
|
720
|
-
transport$1.notifyTransactionId = notifyTransactionId;
|
|
721
|
-
this.monitorTokens.set(uuid, monitorToken);
|
|
722
|
-
transport$1.notifySubscription = this._monitorCharacteristic(transport$1.notifyCharacteristic, uuid, monitorToken, notifyTransactionId);
|
|
723
|
-
transportCache[uuid] = transport$1;
|
|
724
|
-
this.protocolV2Assemblers.set(uuid, new transport.ProtocolV2FrameAssembler());
|
|
725
|
-
if (reactNative.Platform.OS === 'ios') {
|
|
726
|
-
yield new Promise(resolve => {
|
|
727
|
-
setTimeout(resolve, IOS_NOTIFY_READY_DELAY_MS);
|
|
728
|
-
});
|
|
729
|
-
}
|
|
730
|
-
else if (reactNative.Platform.OS === 'android') {
|
|
731
|
-
yield delay(ANDROID_NOTIFY_READY_DELAY_MS);
|
|
732
|
-
}
|
|
733
|
-
const protocolType = yield this.detectProtocol(uuid, expectedProtocol, protocolHint);
|
|
734
|
-
(_f = this.emitter) === null || _f === void 0 ? void 0 : _f.emit('device-connect', {
|
|
602
|
+
const { writeCharacteristic, notifyCharacteristic } = yield this.resolveCharacteristics(device);
|
|
603
|
+
yield this.release(uuid);
|
|
604
|
+
const transport = new BleTransport(device, writeCharacteristic, notifyCharacteristic);
|
|
605
|
+
transport.notifySubscription = this._monitorCharacteristic(transport.notifyCharacteristic, uuid);
|
|
606
|
+
transportCache[uuid] = transport;
|
|
607
|
+
(_a = this.emitter) === null || _a === void 0 ? void 0 : _a.emit('device-connect', {
|
|
735
608
|
name: device.name,
|
|
736
609
|
id: device.id,
|
|
737
610
|
connectId: device.id,
|
|
738
611
|
});
|
|
739
|
-
transport
|
|
740
|
-
|
|
741
|
-
if (transportCache[uuid] !== transport$1) {
|
|
742
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('device disconnect ignored for stale transport: ', device === null || device === void 0 ? void 0 : device.id);
|
|
743
|
-
return;
|
|
744
|
-
}
|
|
745
|
-
try {
|
|
746
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('device disconnect: ', device === null || device === void 0 ? void 0 : device.id);
|
|
747
|
-
(_a = this.emitter) === null || _a === void 0 ? void 0 : _a.emit('device-disconnect', {
|
|
748
|
-
name: device === null || device === void 0 ? void 0 : device.name,
|
|
749
|
-
id: device === null || device === void 0 ? void 0 : device.id,
|
|
750
|
-
connectId: device === null || device === void 0 ? void 0 : device.id,
|
|
751
|
-
});
|
|
752
|
-
if (this.runPromise) {
|
|
753
|
-
const error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleConnectedError);
|
|
754
|
-
this.runPromise.reject(error);
|
|
755
|
-
this.rejectAllProtocolV2Frames(error);
|
|
756
|
-
}
|
|
757
|
-
}
|
|
758
|
-
catch (e) {
|
|
759
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('device disconnect error: ', e);
|
|
760
|
-
}
|
|
761
|
-
finally {
|
|
762
|
-
this.release(uuid, true);
|
|
763
|
-
}
|
|
764
|
-
});
|
|
765
|
-
return { uuid, protocolType };
|
|
612
|
+
this.attachDisconnectSubscription(transport, device, uuid);
|
|
613
|
+
return { uuid };
|
|
766
614
|
});
|
|
767
615
|
}
|
|
768
|
-
_monitorCharacteristic(characteristic, uuid
|
|
616
|
+
_monitorCharacteristic(characteristic, uuid) {
|
|
769
617
|
let bufferLength = 0;
|
|
770
618
|
let buffer$1 = [];
|
|
771
619
|
const subscription = characteristic.monitor((error, c) => {
|
|
772
620
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
773
|
-
const isCurrentMonitor = this.monitorTokens.get(uuid) === monitorToken;
|
|
774
621
|
if (error) {
|
|
775
622
|
Log === null || Log === void 0 ? void 0 : Log.debug(`error monitor ${characteristic.uuid}, deviceId: ${characteristic.deviceID}: ${error}`);
|
|
776
|
-
if (
|
|
777
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('
|
|
623
|
+
if (this.firmwareUploadWriteRecoveryIds.has(uuid)) {
|
|
624
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('notify error ignored during FirmwareUpload write recovery: ', uuid);
|
|
778
625
|
return;
|
|
779
626
|
}
|
|
780
627
|
if (this.runPromise) {
|
|
@@ -790,37 +637,20 @@ class ReactNativeBleTransport {
|
|
|
790
637
|
((_e = error.reason) === null || _e === void 0 ? void 0 : _e.includes('The handle is invalid')) ||
|
|
791
638
|
((_f = error.reason) === null || _f === void 0 ? void 0 : _f.includes('Writing is not permitted')) ||
|
|
792
639
|
((_g = error.reason) === null || _g === void 0 ? void 0 : _g.includes('notify change failed for device'))) {
|
|
793
|
-
|
|
794
|
-
this.runPromise.reject(notifyError);
|
|
795
|
-
this.rejectAllProtocolV2Frames(notifyError);
|
|
640
|
+
this.runPromise.reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleCharacteristicNotifyChangeFailure));
|
|
796
641
|
Log === null || Log === void 0 ? void 0 : Log.debug(`${hdShared.HardwareErrorCode.BleCharacteristicNotifyChangeFailure} ${error.message} ${error.reason}`);
|
|
797
642
|
return;
|
|
798
643
|
}
|
|
799
|
-
|
|
800
|
-
this.runPromise.reject(notifyError);
|
|
801
|
-
this.rejectAllProtocolV2Frames(notifyError);
|
|
644
|
+
this.runPromise.reject(hdShared.ERRORS.TypedError(ERROR));
|
|
802
645
|
Log === null || Log === void 0 ? void 0 : Log.debug(': monitor notify error, and has unreleased Promise', Error);
|
|
803
646
|
}
|
|
804
647
|
return;
|
|
805
648
|
}
|
|
806
|
-
if (!isCurrentMonitor) {
|
|
807
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('monitor data ignored for stale transport: ', uuid, notifyTransactionId);
|
|
808
|
-
return;
|
|
809
|
-
}
|
|
810
649
|
if (!c) {
|
|
811
650
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleMonitorError);
|
|
812
651
|
}
|
|
813
652
|
try {
|
|
814
653
|
const data = buffer.Buffer.from(c.value, 'base64');
|
|
815
|
-
const protocol = this.deviceProtocol.get(uuid);
|
|
816
|
-
if (!protocol) {
|
|
817
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('monitor data ignored before protocol detection: ', uuid);
|
|
818
|
-
return;
|
|
819
|
-
}
|
|
820
|
-
if (protocol === 'V2') {
|
|
821
|
-
this.handleProtocolV2Notification(uuid, new Uint8Array(data));
|
|
822
|
-
return;
|
|
823
|
-
}
|
|
824
654
|
if (isHeaderChunk(data)) {
|
|
825
655
|
bufferLength = data.readInt32BE(5);
|
|
826
656
|
buffer$1 = [...data.subarray(3)];
|
|
@@ -828,7 +658,7 @@ class ReactNativeBleTransport {
|
|
|
828
658
|
else {
|
|
829
659
|
buffer$1 = buffer$1.concat([...data]);
|
|
830
660
|
}
|
|
831
|
-
if (buffer$1.length - transport.
|
|
661
|
+
if (buffer$1.length - transport.COMMON_HEADER_SIZE >= bufferLength) {
|
|
832
662
|
const value = buffer.Buffer.from(buffer$1);
|
|
833
663
|
bufferLength = 0;
|
|
834
664
|
buffer$1 = [];
|
|
@@ -837,65 +667,24 @@ class ReactNativeBleTransport {
|
|
|
837
667
|
}
|
|
838
668
|
catch (error) {
|
|
839
669
|
Log === null || Log === void 0 ? void 0 : Log.debug('monitor data error: ', error);
|
|
840
|
-
|
|
841
|
-
(_j = this.runPromise) === null || _j === void 0 ? void 0 : _j.reject(notifyError);
|
|
842
|
-
this.rejectAllProtocolV2Frames(notifyError);
|
|
670
|
+
(_j = this.runPromise) === null || _j === void 0 ? void 0 : _j.reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleWriteCharacteristicError));
|
|
843
671
|
}
|
|
844
|
-
},
|
|
672
|
+
}, uuid);
|
|
845
673
|
return subscription;
|
|
846
674
|
}
|
|
847
|
-
release(uuid
|
|
848
|
-
var _a, _b, _c
|
|
675
|
+
release(uuid) {
|
|
676
|
+
var _a, _b, _c;
|
|
849
677
|
return __awaiter(this, void 0, void 0, function* () {
|
|
850
678
|
const transport = transportCache[uuid];
|
|
851
|
-
if (this.runPromise) {
|
|
852
|
-
const error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleForceCleanRunPromise);
|
|
853
|
-
this.runPromise.reject(error);
|
|
854
|
-
this.runPromise = null;
|
|
855
|
-
this.rejectAllProtocolV2Frames(error);
|
|
856
|
-
this.activeProtocolV2Call = null;
|
|
857
|
-
}
|
|
858
|
-
else {
|
|
859
|
-
this.resetProtocolV2Frames(uuid);
|
|
860
|
-
}
|
|
861
|
-
if (reactNative.Platform.OS === 'android' && !onclose && transport) {
|
|
862
|
-
(_a = this.protocolV2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
|
|
863
|
-
this.resetProtocolV2Frames(uuid);
|
|
864
|
-
if (((_b = this.activeProtocolV2Call) === null || _b === void 0 ? void 0 : _b.uuid) === uuid) {
|
|
865
|
-
this.activeProtocolV2Call = null;
|
|
866
|
-
}
|
|
867
|
-
return Promise.resolve(true);
|
|
868
|
-
}
|
|
869
679
|
if (transport) {
|
|
870
|
-
if (this.monitorTokens.get(uuid) === transport.monitorToken) {
|
|
871
|
-
this.monitorTokens.delete(uuid);
|
|
872
|
-
}
|
|
873
680
|
Log === null || Log === void 0 ? void 0 : Log.debug('release: removing disconnect subscription for device: ', uuid);
|
|
874
|
-
(
|
|
681
|
+
(_a = transport.disconnectSubscription) === null || _a === void 0 ? void 0 : _a.remove();
|
|
875
682
|
transport.disconnectSubscription = undefined;
|
|
876
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('release: removing notify subscription, characteristic: ', (
|
|
877
|
-
(
|
|
683
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('release: removing notify subscription, characteristic: ', (_b = transport.notifyCharacteristic) === null || _b === void 0 ? void 0 : _b.uuid);
|
|
684
|
+
(_c = transport.notifySubscription) === null || _c === void 0 ? void 0 : _c.remove();
|
|
878
685
|
transport.notifySubscription = undefined;
|
|
879
|
-
if (transport.notifyTransactionId) {
|
|
880
|
-
try {
|
|
881
|
-
yield ((_f = this.blePlxManager) === null || _f === void 0 ? void 0 : _f.cancelTransaction(transport.notifyTransactionId));
|
|
882
|
-
}
|
|
883
|
-
catch (e) {
|
|
884
|
-
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);
|
|
885
|
-
}
|
|
886
|
-
}
|
|
887
686
|
delete transportCache[uuid];
|
|
888
|
-
|
|
889
|
-
this.deviceProtocol.delete(uuid);
|
|
890
|
-
this.deviceProtocolHints.delete(uuid);
|
|
891
|
-
(_g = this.protocolV2Assemblers.get(uuid)) === null || _g === void 0 ? void 0 : _g.reset();
|
|
892
|
-
this.protocolV2Assemblers.delete(uuid);
|
|
893
|
-
this.resetProtocolV2Frames(uuid);
|
|
894
|
-
try {
|
|
895
|
-
yield ((_h = this.blePlxManager) === null || _h === void 0 ? void 0 : _h.cancelTransaction(uuid));
|
|
896
|
-
}
|
|
897
|
-
catch (e) {
|
|
898
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('release: cancel transaction error (ignored): ', (e === null || e === void 0 ? void 0 : e.message) || e);
|
|
687
|
+
if (reactNative.Platform.OS === 'android') ;
|
|
899
688
|
}
|
|
900
689
|
return Promise.resolve(true);
|
|
901
690
|
});
|
|
@@ -905,7 +694,7 @@ class ReactNativeBleTransport {
|
|
|
905
694
|
yield this.call(session, name, data);
|
|
906
695
|
});
|
|
907
696
|
}
|
|
908
|
-
call(uuid, name, data
|
|
697
|
+
call(uuid, name, data) {
|
|
909
698
|
return __awaiter(this, void 0, void 0, function* () {
|
|
910
699
|
if (this.stopped) {
|
|
911
700
|
return Promise.reject(hdShared.ERRORS.TypedError('Transport stopped.'));
|
|
@@ -918,10 +707,12 @@ class ReactNativeBleTransport {
|
|
|
918
707
|
if (this.runPromise && !forceRun) {
|
|
919
708
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.TransportCallInProgress);
|
|
920
709
|
}
|
|
921
|
-
const
|
|
922
|
-
if (!
|
|
923
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.
|
|
710
|
+
const transport$1 = transportCache[uuid];
|
|
711
|
+
if (!transport$1) {
|
|
712
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.TransportNotFound);
|
|
924
713
|
}
|
|
714
|
+
this.runPromise = hdShared.createDeferred();
|
|
715
|
+
const messages = this._messages;
|
|
925
716
|
if (name === 'ResourceUpdate' || name === 'ResourceAck') {
|
|
926
717
|
Log === null || Log === void 0 ? void 0 : Log.debug('transport-react-native', 'call-', ' name: ', name, ' data: ', {
|
|
927
718
|
file_name: data === null || data === void 0 ? void 0 : data.file_name,
|
|
@@ -929,29 +720,12 @@ class ReactNativeBleTransport {
|
|
|
929
720
|
});
|
|
930
721
|
}
|
|
931
722
|
else if (transport.LogBlockCommand.has(name)) {
|
|
932
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('transport-react-native', 'call-', ' name: ', name
|
|
723
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('transport-react-native', 'call-', ' name: ', name);
|
|
933
724
|
}
|
|
934
725
|
else {
|
|
935
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('transport-react-native', 'call-', ' name: ', name, ' data: ', data
|
|
936
|
-
}
|
|
937
|
-
if (protocol === 'V2') {
|
|
938
|
-
return this.callProtocolV2(uuid, name, data, options);
|
|
939
|
-
}
|
|
940
|
-
return this.callProtocolV1(uuid, name, data, options);
|
|
941
|
-
});
|
|
942
|
-
}
|
|
943
|
-
callProtocolV1(uuid, name, data, options) {
|
|
944
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
945
|
-
if (!this._messages) {
|
|
946
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.TransportNotConfigured);
|
|
726
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('transport-react-native', 'call-', ' name: ', name, ' data: ', data);
|
|
947
727
|
}
|
|
948
|
-
const
|
|
949
|
-
const runPromise = hdShared.createDeferred();
|
|
950
|
-
runPromise.promise.catch(() => undefined);
|
|
951
|
-
this.runPromise = runPromise;
|
|
952
|
-
const messages = this._messages;
|
|
953
|
-
const buffers = ProtocolV1.encodeTransportPackets(messages, name, data);
|
|
954
|
-
let timeout;
|
|
728
|
+
const buffers = buildBuffers(messages, name, data);
|
|
955
729
|
function writeChunkedData(buffers, writeFunction, onError) {
|
|
956
730
|
return __awaiter(this, void 0, void 0, function* () {
|
|
957
731
|
const packetCapacity = reactNative.Platform.OS === 'ios' ? IOS_PACKET_LENGTH : ANDROID_PACKET_LENGTH;
|
|
@@ -975,15 +749,90 @@ class ReactNativeBleTransport {
|
|
|
975
749
|
}
|
|
976
750
|
});
|
|
977
751
|
}
|
|
752
|
+
function writeFirmwareUploadChunkedData(buffers, writeFunction, onError) {
|
|
753
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
754
|
+
let index = 0;
|
|
755
|
+
let packetsWritten = 0;
|
|
756
|
+
let chunk = ByteBuffer__default["default"].allocate(FIRMWARE_UPLOAD_WRITE_PACKET_CAPACITY);
|
|
757
|
+
while (index < buffers.length) {
|
|
758
|
+
const buffer = buffers[index].toBuffer();
|
|
759
|
+
chunk.append(buffer);
|
|
760
|
+
index += 1;
|
|
761
|
+
if (chunk.offset === FIRMWARE_UPLOAD_WRITE_PACKET_CAPACITY || index >= buffers.length) {
|
|
762
|
+
chunk.reset();
|
|
763
|
+
try {
|
|
764
|
+
yield writeFunction(chunk.toString('base64'));
|
|
765
|
+
packetsWritten += 1;
|
|
766
|
+
chunk = ByteBuffer__default["default"].allocate(FIRMWARE_UPLOAD_WRITE_PACKET_CAPACITY);
|
|
767
|
+
if (packetsWritten % FIRMWARE_UPLOAD_WRITE_BURST_SIZE === 0 && index < buffers.length) {
|
|
768
|
+
yield delay(FIRMWARE_UPLOAD_WRITE_PAUSE_MS);
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
catch (e) {
|
|
772
|
+
onError(e);
|
|
773
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleWriteCharacteristicError);
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
if (packetsWritten > 0) {
|
|
778
|
+
yield delay(FIRMWARE_UPLOAD_WRITE_FLUSH_DELAY_MS);
|
|
779
|
+
}
|
|
780
|
+
});
|
|
781
|
+
}
|
|
978
782
|
if (name === 'EmmcFileWrite') {
|
|
979
|
-
yield writeChunkedData(buffers, data => transport.writeWithRetry(data), e => {
|
|
783
|
+
yield writeChunkedData(buffers, data => transport$1.writeWithRetry(data), e => {
|
|
980
784
|
this.runPromise = null;
|
|
981
785
|
Log === null || Log === void 0 ? void 0 : Log.error('writeCharacteristic write error: ', e);
|
|
982
786
|
});
|
|
983
787
|
}
|
|
984
788
|
else if (name === 'FirmwareUpload') {
|
|
985
|
-
|
|
986
|
-
|
|
789
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] FirmwareUpload write uses throttled BLE packets:', {
|
|
790
|
+
packetCapacity: FIRMWARE_UPLOAD_WRITE_PACKET_CAPACITY,
|
|
791
|
+
burstSize: FIRMWARE_UPLOAD_WRITE_BURST_SIZE,
|
|
792
|
+
pauseMs: FIRMWARE_UPLOAD_WRITE_PAUSE_MS,
|
|
793
|
+
flushDelayMs: FIRMWARE_UPLOAD_WRITE_FLUSH_DELAY_MS,
|
|
794
|
+
maxRetries: FIRMWARE_UPLOAD_WRITE_MAX_RETRIES,
|
|
795
|
+
});
|
|
796
|
+
yield writeFirmwareUploadChunkedData(buffers, (data) => __awaiter(this, void 0, void 0, function* () {
|
|
797
|
+
let attempt = 0;
|
|
798
|
+
while (true) {
|
|
799
|
+
try {
|
|
800
|
+
yield transport$1.writeCharacteristic.writeWithoutResponse(data);
|
|
801
|
+
return;
|
|
802
|
+
}
|
|
803
|
+
catch (error) {
|
|
804
|
+
const retryType = getFirmwareUploadWriteRetryType(error);
|
|
805
|
+
if (!retryType || attempt >= FIRMWARE_UPLOAD_WRITE_MAX_RETRIES) {
|
|
806
|
+
throw error;
|
|
807
|
+
}
|
|
808
|
+
const shouldReconnect = retryType === 'reconnectable';
|
|
809
|
+
const delayMs = shouldReconnect
|
|
810
|
+
? FIRMWARE_UPLOAD_RECONNECT_RETRY_DELAY_MS
|
|
811
|
+
: resolveFirmwareUploadRetryDelay(attempt);
|
|
812
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] FirmwareUpload write retry:', {
|
|
813
|
+
attempt: attempt + 1,
|
|
814
|
+
delayMs,
|
|
815
|
+
reconnect: shouldReconnect,
|
|
816
|
+
error,
|
|
817
|
+
});
|
|
818
|
+
if (shouldReconnect) {
|
|
819
|
+
this.firmwareUploadWriteRecoveryIds.add(uuid);
|
|
820
|
+
}
|
|
821
|
+
yield delay(delayMs);
|
|
822
|
+
attempt += 1;
|
|
823
|
+
if (shouldReconnect) {
|
|
824
|
+
try {
|
|
825
|
+
yield this.reconnectFirmwareUploadTransport(uuid, transport$1);
|
|
826
|
+
}
|
|
827
|
+
catch (e) {
|
|
828
|
+
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] FirmwareUpload reconnect error:', e);
|
|
829
|
+
if (attempt >= FIRMWARE_UPLOAD_WRITE_MAX_RETRIES) {
|
|
830
|
+
throw e;
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
}
|
|
987
836
|
}), e => {
|
|
988
837
|
this.runPromise = null;
|
|
989
838
|
Log === null || Log === void 0 ? void 0 : Log.error('writeCharacteristic write error: ', e);
|
|
@@ -993,7 +842,7 @@ class ReactNativeBleTransport {
|
|
|
993
842
|
for (const o of buffers) {
|
|
994
843
|
const outData = o.toString('base64');
|
|
995
844
|
try {
|
|
996
|
-
yield transport.writeCharacteristic.writeWithoutResponse(outData);
|
|
845
|
+
yield transport$1.writeCharacteristic.writeWithoutResponse(outData);
|
|
997
846
|
}
|
|
998
847
|
catch (e) {
|
|
999
848
|
Log === null || Log === void 0 ? void 0 : Log.debug('writeCharacteristic write error: ', e);
|
|
@@ -1011,40 +860,20 @@ class ReactNativeBleTransport {
|
|
|
1011
860
|
}
|
|
1012
861
|
}
|
|
1013
862
|
try {
|
|
1014
|
-
const response = yield
|
|
1015
|
-
runPromise.promise,
|
|
1016
|
-
new Promise((_, reject) => {
|
|
1017
|
-
if (options === null || options === void 0 ? void 0 : options.timeoutMs) {
|
|
1018
|
-
timeout = setTimeout(() => {
|
|
1019
|
-
const error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleTimeoutError, `BLE response timeout after ${options.timeoutMs}ms for ${name}`);
|
|
1020
|
-
runPromise.reject(error);
|
|
1021
|
-
reject(error);
|
|
1022
|
-
}, options.timeoutMs);
|
|
1023
|
-
}
|
|
1024
|
-
}),
|
|
1025
|
-
]);
|
|
863
|
+
const response = yield this.runPromise.promise;
|
|
1026
864
|
if (typeof response !== 'string') {
|
|
1027
865
|
throw new Error('Returning data is not string.');
|
|
1028
866
|
}
|
|
1029
867
|
Log === null || Log === void 0 ? void 0 : Log.debug('receive data: ', response);
|
|
1030
|
-
const jsonData =
|
|
868
|
+
const jsonData = receiveOne(messages, response);
|
|
1031
869
|
return check.call(jsonData);
|
|
1032
870
|
}
|
|
1033
871
|
catch (e) {
|
|
1034
|
-
|
|
1035
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V1 Initialize probe call failed:', e);
|
|
1036
|
-
}
|
|
1037
|
-
else {
|
|
1038
|
-
Log === null || Log === void 0 ? void 0 : Log.error('call error: ', e);
|
|
1039
|
-
}
|
|
872
|
+
Log === null || Log === void 0 ? void 0 : Log.error('call error: ', e);
|
|
1040
873
|
throw e;
|
|
1041
874
|
}
|
|
1042
875
|
finally {
|
|
1043
|
-
|
|
1044
|
-
clearTimeout(timeout);
|
|
1045
|
-
if (this.runPromise === runPromise) {
|
|
1046
|
-
this.runPromise = null;
|
|
1047
|
-
}
|
|
876
|
+
this.runPromise = null;
|
|
1048
877
|
}
|
|
1049
878
|
});
|
|
1050
879
|
}
|
|
@@ -1052,7 +881,7 @@ class ReactNativeBleTransport {
|
|
|
1052
881
|
this.stopped = true;
|
|
1053
882
|
}
|
|
1054
883
|
disconnect(session) {
|
|
1055
|
-
var _a, _b, _c, _d, _e
|
|
884
|
+
var _a, _b, _c, _d, _e;
|
|
1056
885
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1057
886
|
Log === null || Log === void 0 ? void 0 : Log.debug('transport-react-native transport resetSession: ', session);
|
|
1058
887
|
const transport = transportCache[session];
|
|
@@ -1101,16 +930,9 @@ class ReactNativeBleTransport {
|
|
|
1101
930
|
if (transportCache[session]) {
|
|
1102
931
|
delete transportCache[session];
|
|
1103
932
|
}
|
|
1104
|
-
this.deviceProtocol.delete(session);
|
|
1105
|
-
this.deviceProtocolHints.delete(session);
|
|
1106
|
-
this.protocolV2Assemblers.delete(session);
|
|
1107
|
-
this.resetProtocolV2Frames(session);
|
|
1108
|
-
if (((_d = this.activeProtocolV2Call) === null || _d === void 0 ? void 0 : _d.uuid) === session) {
|
|
1109
|
-
this.activeProtocolV2Call = null;
|
|
1110
|
-
}
|
|
1111
933
|
try {
|
|
1112
|
-
(
|
|
1113
|
-
name: (
|
|
934
|
+
(_d = this.emitter) === null || _d === void 0 ? void 0 : _d.emit('device-disconnect', {
|
|
935
|
+
name: (_e = transport === null || transport === void 0 ? void 0 : transport.device) === null || _e === void 0 ? void 0 : _e.name,
|
|
1114
936
|
id: session,
|
|
1115
937
|
connectId: session,
|
|
1116
938
|
});
|
|
@@ -1126,367 +948,6 @@ class ReactNativeBleTransport {
|
|
|
1126
948
|
if (this.runPromise) ;
|
|
1127
949
|
this.runPromise = null;
|
|
1128
950
|
}
|
|
1129
|
-
getCachedTransport(uuid) {
|
|
1130
|
-
const transport = transportCache[uuid];
|
|
1131
|
-
if (!transport) {
|
|
1132
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.TransportNotFound);
|
|
1133
|
-
}
|
|
1134
|
-
return transport;
|
|
1135
|
-
}
|
|
1136
|
-
createProtocolMismatchError(expected) {
|
|
1137
|
-
return hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Device protocol mismatch: expected ${expected}, but device did not respond to expected protocol`);
|
|
1138
|
-
}
|
|
1139
|
-
createProtocolDetectionError() {
|
|
1140
|
-
return hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleTimeoutError, 'Unable to detect BLE protocol: device did not respond to Protocol V1 Initialize or Protocol V2 Ping');
|
|
1141
|
-
}
|
|
1142
|
-
clearProbeProtocol(uuid, protocol) {
|
|
1143
|
-
if (this.deviceProtocol.get(uuid) === protocol) {
|
|
1144
|
-
this.deviceProtocol.delete(uuid);
|
|
1145
|
-
}
|
|
1146
|
-
}
|
|
1147
|
-
detectProtocol(uuid, expectedProtocol, protocolHint) {
|
|
1148
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1149
|
-
if (expectedProtocol === 'V1') {
|
|
1150
|
-
if (yield this.probeProtocolV1(uuid)) {
|
|
1151
|
-
this.deviceProtocol.set(uuid, 'V1');
|
|
1152
|
-
Log === null || Log === void 0 ? void 0 : Log.debug(`[ReactNativeBleTransport] detectProtocol: uuid=${uuid} -> V1 (expected)`);
|
|
1153
|
-
return 'V1';
|
|
1154
|
-
}
|
|
1155
|
-
throw this.createProtocolMismatchError(expectedProtocol);
|
|
1156
|
-
}
|
|
1157
|
-
if (expectedProtocol === 'V2') {
|
|
1158
|
-
this.deviceProtocol.set(uuid, 'V2');
|
|
1159
|
-
Log === null || Log === void 0 ? void 0 : Log.debug(`[ReactNativeBleTransport] detectProtocol: uuid=${uuid} -> V2 (expected)`);
|
|
1160
|
-
return 'V2';
|
|
1161
|
-
}
|
|
1162
|
-
if (protocolHint === 'V2') {
|
|
1163
|
-
this.deviceProtocol.set(uuid, 'V2');
|
|
1164
|
-
Log === null || Log === void 0 ? void 0 : Log.debug(`[ReactNativeBleTransport] detectProtocol: uuid=${uuid} -> V2 (hint)`);
|
|
1165
|
-
return 'V2';
|
|
1166
|
-
}
|
|
1167
|
-
if (this.deviceProtocol.get(uuid) === 'V2') {
|
|
1168
|
-
this.deviceProtocol.set(uuid, 'V2');
|
|
1169
|
-
Log === null || Log === void 0 ? void 0 : Log.debug(`[ReactNativeBleTransport] detectProtocol: uuid=${uuid} -> V2 (cached)`);
|
|
1170
|
-
return 'V2';
|
|
1171
|
-
}
|
|
1172
|
-
const protocolV1Detected = yield this.probeProtocolV1(uuid);
|
|
1173
|
-
if (protocolV1Detected) {
|
|
1174
|
-
this.deviceProtocol.set(uuid, 'V1');
|
|
1175
|
-
Log === null || Log === void 0 ? void 0 : Log.debug(`[ReactNativeBleTransport] detectProtocol: uuid=${uuid} -> V1`);
|
|
1176
|
-
return 'V1';
|
|
1177
|
-
}
|
|
1178
|
-
yield this.resetProbeStateAfterProtocolProbe(uuid, 'V1');
|
|
1179
|
-
if (yield this.probeProtocolV2(uuid)) {
|
|
1180
|
-
this.deviceProtocol.set(uuid, 'V2');
|
|
1181
|
-
Log === null || Log === void 0 ? void 0 : Log.debug(`[ReactNativeBleTransport] detectProtocol: uuid=${uuid} -> V2`);
|
|
1182
|
-
return 'V2';
|
|
1183
|
-
}
|
|
1184
|
-
this.deviceProtocol.delete(uuid);
|
|
1185
|
-
throw this.createProtocolDetectionError();
|
|
1186
|
-
});
|
|
1187
|
-
}
|
|
1188
|
-
resetProbeStateAfterProtocolProbe(uuid, protocol) {
|
|
1189
|
-
var _a, _b, _c, _d;
|
|
1190
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1191
|
-
const transport = transportCache[uuid];
|
|
1192
|
-
(_a = this.protocolV2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
|
|
1193
|
-
this.resetProtocolV2Frames(uuid);
|
|
1194
|
-
if (((_b = this.activeProtocolV2Call) === null || _b === void 0 ? void 0 : _b.uuid) === uuid) {
|
|
1195
|
-
this.activeProtocolV2Call = null;
|
|
1196
|
-
}
|
|
1197
|
-
if (this.runPromise) {
|
|
1198
|
-
const error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleForceCleanRunPromise);
|
|
1199
|
-
this.runPromise.reject(error);
|
|
1200
|
-
this.runPromise = null;
|
|
1201
|
-
}
|
|
1202
|
-
if (!transport)
|
|
1203
|
-
return;
|
|
1204
|
-
const previousNotifyTransactionId = transport.notifyTransactionId;
|
|
1205
|
-
if (this.monitorTokens.get(uuid) === transport.monitorToken) {
|
|
1206
|
-
this.monitorTokens.delete(uuid);
|
|
1207
|
-
}
|
|
1208
|
-
(_c = transport.notifySubscription) === null || _c === void 0 ? void 0 : _c.remove();
|
|
1209
|
-
transport.notifySubscription = undefined;
|
|
1210
|
-
if (previousNotifyTransactionId) {
|
|
1211
|
-
try {
|
|
1212
|
-
yield ((_d = this.blePlxManager) === null || _d === void 0 ? void 0 : _d.cancelTransaction(previousNotifyTransactionId));
|
|
1213
|
-
}
|
|
1214
|
-
catch (error) {
|
|
1215
|
-
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);
|
|
1216
|
-
}
|
|
1217
|
-
}
|
|
1218
|
-
const monitorToken = this.nextMonitorToken;
|
|
1219
|
-
this.nextMonitorToken += 1;
|
|
1220
|
-
const notifyTransactionId = `${uuid}:notify:${monitorToken}`;
|
|
1221
|
-
transport.monitorToken = monitorToken;
|
|
1222
|
-
transport.notifyTransactionId = notifyTransactionId;
|
|
1223
|
-
this.monitorTokens.set(uuid, monitorToken);
|
|
1224
|
-
transport.notifySubscription = this._monitorCharacteristic(transport.notifyCharacteristic, uuid, monitorToken, notifyTransactionId);
|
|
1225
|
-
if (reactNative.Platform.OS === 'ios') {
|
|
1226
|
-
yield new Promise(resolve => {
|
|
1227
|
-
setTimeout(resolve, IOS_NOTIFY_READY_DELAY_MS);
|
|
1228
|
-
});
|
|
1229
|
-
}
|
|
1230
|
-
});
|
|
1231
|
-
}
|
|
1232
|
-
probeProtocolV1(uuid) {
|
|
1233
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1234
|
-
if (!this._messages) {
|
|
1235
|
-
return false;
|
|
1236
|
-
}
|
|
1237
|
-
try {
|
|
1238
|
-
this.deviceProtocol.set(uuid, 'V1');
|
|
1239
|
-
yield this.callProtocolV1(uuid, 'Initialize', {}, { timeoutMs: PROTOCOL_PROBE_TIMEOUT_MS });
|
|
1240
|
-
return true;
|
|
1241
|
-
}
|
|
1242
|
-
catch (error) {
|
|
1243
|
-
this.clearProbeProtocol(uuid, 'V1');
|
|
1244
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V1 Initialize probe failed:', error);
|
|
1245
|
-
return false;
|
|
1246
|
-
}
|
|
1247
|
-
});
|
|
1248
|
-
}
|
|
1249
|
-
probeProtocolV2(uuid) {
|
|
1250
|
-
var _a;
|
|
1251
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1252
|
-
if (!this._messages || !this._messagesV2) {
|
|
1253
|
-
return false;
|
|
1254
|
-
}
|
|
1255
|
-
this.deviceProtocol.set(uuid, 'V2');
|
|
1256
|
-
(_a = this.protocolV2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
|
|
1257
|
-
const detected = yield transport.probeProtocolV2({
|
|
1258
|
-
call: (name, data, options) => this.callProtocolV2(uuid, name, data, options),
|
|
1259
|
-
timeoutMs: PROTOCOL_V2_PROBE_TIMEOUT_MS,
|
|
1260
|
-
logger: Log,
|
|
1261
|
-
logPrefix: 'ProtocolV2 RN-BLE',
|
|
1262
|
-
onProbeFailed: () => {
|
|
1263
|
-
var _a;
|
|
1264
|
-
(_a = this.protocolV2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
|
|
1265
|
-
this.resetProtocolV2Frames(uuid);
|
|
1266
|
-
},
|
|
1267
|
-
});
|
|
1268
|
-
if (!detected) {
|
|
1269
|
-
this.clearProbeProtocol(uuid, 'V2');
|
|
1270
|
-
}
|
|
1271
|
-
return detected;
|
|
1272
|
-
});
|
|
1273
|
-
}
|
|
1274
|
-
handleProtocolV2Notification(uuid, data) {
|
|
1275
|
-
var _a, _b, _c;
|
|
1276
|
-
try {
|
|
1277
|
-
if (!this.runPromise || ((_a = this.activeProtocolV2Call) === null || _a === void 0 ? void 0 : _a.uuid) !== uuid) {
|
|
1278
|
-
(_b = this.protocolV2Assemblers.get(uuid)) === null || _b === void 0 ? void 0 : _b.reset();
|
|
1279
|
-
this.resetProtocolV2Frames(uuid);
|
|
1280
|
-
return;
|
|
1281
|
-
}
|
|
1282
|
-
if (data.length === 0)
|
|
1283
|
-
return;
|
|
1284
|
-
const assembler = this.protocolV2Assemblers.get(uuid);
|
|
1285
|
-
if (!assembler)
|
|
1286
|
-
return;
|
|
1287
|
-
let frameData = assembler.push(data);
|
|
1288
|
-
while (frameData) {
|
|
1289
|
-
this.resolveProtocolV2Frame(uuid, frameData);
|
|
1290
|
-
frameData = assembler.push(new Uint8Array(0));
|
|
1291
|
-
}
|
|
1292
|
-
}
|
|
1293
|
-
catch (error) {
|
|
1294
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V2 notification error:', error);
|
|
1295
|
-
const notifyError = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleWriteCharacteristicError);
|
|
1296
|
-
(_c = this.runPromise) === null || _c === void 0 ? void 0 : _c.reject(notifyError);
|
|
1297
|
-
this.rejectAllProtocolV2Frames(notifyError);
|
|
1298
|
-
}
|
|
1299
|
-
}
|
|
1300
|
-
getProtocolV2FrameQueue(uuid) {
|
|
1301
|
-
let queue = this.protocolV2FrameQueues.get(uuid);
|
|
1302
|
-
if (!queue) {
|
|
1303
|
-
queue = [];
|
|
1304
|
-
this.protocolV2FrameQueues.set(uuid, queue);
|
|
1305
|
-
}
|
|
1306
|
-
return queue;
|
|
1307
|
-
}
|
|
1308
|
-
resolveProtocolV2Frame(uuid, frame) {
|
|
1309
|
-
const framePromise = this.protocolV2FramePromises.get(uuid);
|
|
1310
|
-
if (framePromise) {
|
|
1311
|
-
framePromise.resolve(frame);
|
|
1312
|
-
this.protocolV2FramePromises.delete(uuid);
|
|
1313
|
-
return;
|
|
1314
|
-
}
|
|
1315
|
-
this.getProtocolV2FrameQueue(uuid).push(frame);
|
|
1316
|
-
}
|
|
1317
|
-
rejectAllProtocolV2Frames(error) {
|
|
1318
|
-
this.protocolV2FrameQueues.clear();
|
|
1319
|
-
for (const framePromise of this.protocolV2FramePromises.values()) {
|
|
1320
|
-
framePromise.reject(error);
|
|
1321
|
-
}
|
|
1322
|
-
this.protocolV2FramePromises.clear();
|
|
1323
|
-
}
|
|
1324
|
-
resetProtocolV2Frames(uuid) {
|
|
1325
|
-
this.protocolV2FrameQueues.delete(uuid);
|
|
1326
|
-
this.protocolV2FramePromises.delete(uuid);
|
|
1327
|
-
}
|
|
1328
|
-
isActiveProtocolV2Call(uuid, token) {
|
|
1329
|
-
var _a;
|
|
1330
|
-
return ((_a = this.activeProtocolV2Call) === null || _a === void 0 ? void 0 : _a.uuid) === uuid && this.activeProtocolV2Call.token === token;
|
|
1331
|
-
}
|
|
1332
|
-
readProtocolV2Frame(uuid) {
|
|
1333
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1334
|
-
const queuedFrame = this.getProtocolV2FrameQueue(uuid).shift();
|
|
1335
|
-
if (queuedFrame) {
|
|
1336
|
-
return queuedFrame;
|
|
1337
|
-
}
|
|
1338
|
-
const framePromise = hdShared.createDeferred();
|
|
1339
|
-
this.protocolV2FramePromises.set(uuid, framePromise);
|
|
1340
|
-
try {
|
|
1341
|
-
return yield framePromise.promise;
|
|
1342
|
-
}
|
|
1343
|
-
finally {
|
|
1344
|
-
if (this.protocolV2FramePromises.get(uuid) === framePromise) {
|
|
1345
|
-
this.protocolV2FramePromises.delete(uuid);
|
|
1346
|
-
}
|
|
1347
|
-
}
|
|
1348
|
-
});
|
|
1349
|
-
}
|
|
1350
|
-
writeProtocolV2Frame(transport, frame, options) {
|
|
1351
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1352
|
-
const tuning = getProtocolV2BleTuning();
|
|
1353
|
-
const packetCapacity = resolveProtocolV2PacketCapacity({
|
|
1354
|
-
platform: reactNative.Platform.OS,
|
|
1355
|
-
iosPacketLength: tuning.iosPacketLength,
|
|
1356
|
-
androidPacketLength: tuning.androidPacketLength,
|
|
1357
|
-
mtu: reactNative.Platform.OS === 'android' ? transport.mtuSize : undefined,
|
|
1358
|
-
});
|
|
1359
|
-
const writeWithResponse = !!(options === null || options === void 0 ? void 0 : options.writeWithResponse) || (!!(options === null || options === void 0 ? void 0 : options.highVolume) && tuning.highVolumeWriteWithResponse);
|
|
1360
|
-
const writeMode = resolveBleWriteMode(transport.writeCharacteristic, writeWithResponse ? 'withResponse' : 'withoutResponse');
|
|
1361
|
-
const shouldThrottle = !!(options === null || options === void 0 ? void 0 : options.highVolume) && writeMode === 'withoutResponse';
|
|
1362
|
-
let packetsWritten = 0;
|
|
1363
|
-
try {
|
|
1364
|
-
for (let offset = 0; offset < frame.length; offset += packetCapacity) {
|
|
1365
|
-
const chunk = frame.slice(offset, offset + packetCapacity);
|
|
1366
|
-
const base64 = buffer.Buffer.from(chunk).toString('base64');
|
|
1367
|
-
if (writeMode === 'withResponse') {
|
|
1368
|
-
yield transport.writeCharacteristic.writeWithResponse(base64);
|
|
1369
|
-
}
|
|
1370
|
-
else {
|
|
1371
|
-
yield transport.writeCharacteristic.writeWithoutResponse(base64);
|
|
1372
|
-
}
|
|
1373
|
-
packetsWritten += 1;
|
|
1374
|
-
if (shouldThrottle &&
|
|
1375
|
-
packetsWritten % tuning.highVolumeWriteBurstSize === 0 &&
|
|
1376
|
-
offset + packetCapacity < frame.length) {
|
|
1377
|
-
yield delay(tuning.highVolumeWritePauseMs);
|
|
1378
|
-
}
|
|
1379
|
-
}
|
|
1380
|
-
if (shouldThrottle) {
|
|
1381
|
-
yield delay(tuning.highVolumeWriteFlushDelayMs);
|
|
1382
|
-
}
|
|
1383
|
-
}
|
|
1384
|
-
catch (error) {
|
|
1385
|
-
if ((options === null || options === void 0 ? void 0 : options.highVolume) && !writeWithResponse && packetsWritten === 0) {
|
|
1386
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V2 high-volume writeWithoutResponse failed before data was sent, fallback to writeWithResponse:', error);
|
|
1387
|
-
yield this.writeProtocolV2Frame(transport, frame, {
|
|
1388
|
-
highVolume: true,
|
|
1389
|
-
writeWithResponse: true,
|
|
1390
|
-
});
|
|
1391
|
-
return;
|
|
1392
|
-
}
|
|
1393
|
-
throw error;
|
|
1394
|
-
}
|
|
1395
|
-
});
|
|
1396
|
-
}
|
|
1397
|
-
callProtocolV2(uuid, name, data, options) {
|
|
1398
|
-
var _a, _b, _c, _d;
|
|
1399
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
1400
|
-
if (!this._messages || !this._messagesV2) {
|
|
1401
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.TransportNotConfigured);
|
|
1402
|
-
}
|
|
1403
|
-
const forceRun = name === 'Initialize' || name === 'Cancel' || name === 'GetProtoVersion';
|
|
1404
|
-
if (this.runPromise) {
|
|
1405
|
-
if (!forceRun) {
|
|
1406
|
-
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.TransportCallInProgress);
|
|
1407
|
-
}
|
|
1408
|
-
const error = hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleForceCleanRunPromise);
|
|
1409
|
-
this.runPromise.reject(error);
|
|
1410
|
-
this.rejectAllProtocolV2Frames(error);
|
|
1411
|
-
this.runPromise = null;
|
|
1412
|
-
this.activeProtocolV2Call = null;
|
|
1413
|
-
}
|
|
1414
|
-
const transport$1 = this.getCachedTransport(uuid);
|
|
1415
|
-
const runPromise = hdShared.createDeferred();
|
|
1416
|
-
runPromise.promise.catch(() => undefined);
|
|
1417
|
-
this.runPromise = runPromise;
|
|
1418
|
-
const callToken = this.nextProtocolV2CallToken++;
|
|
1419
|
-
this.activeProtocolV2Call = { uuid, token: callToken };
|
|
1420
|
-
(_a = this.protocolV2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
|
|
1421
|
-
this.resetProtocolV2Frames(uuid);
|
|
1422
|
-
let completed = false;
|
|
1423
|
-
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 });
|
|
1424
|
-
const highVolumeWrite = transport.LogBlockCommand.has(name);
|
|
1425
|
-
if (highVolumeWrite) {
|
|
1426
|
-
const tuning = getProtocolV2BleTuning();
|
|
1427
|
-
Log === null || Log === void 0 ? void 0 : Log.debug('[ReactNativeBleTransport] Protocol V2 high-volume write uses throttled writeWithoutResponse:', name, {
|
|
1428
|
-
packetCapacity: reactNative.Platform.OS === 'ios' ? tuning.iosPacketLength : tuning.androidPacketLength,
|
|
1429
|
-
burstSize: tuning.highVolumeWriteBurstSize,
|
|
1430
|
-
pauseMs: tuning.highVolumeWritePauseMs,
|
|
1431
|
-
flushDelayMs: tuning.highVolumeWriteFlushDelayMs,
|
|
1432
|
-
writeWithResponse: tuning.highVolumeWriteWithResponse,
|
|
1433
|
-
});
|
|
1434
|
-
}
|
|
1435
|
-
try {
|
|
1436
|
-
const session = new transport.ProtocolV2Session({
|
|
1437
|
-
schemas: {
|
|
1438
|
-
protocolV1: this._messages,
|
|
1439
|
-
protocolV2: this._messagesV2,
|
|
1440
|
-
},
|
|
1441
|
-
router: transport.PROTOCOL_V2_CHANNEL_BLE_UART,
|
|
1442
|
-
writeFrame: (frame) => __awaiter(this, void 0, void 0, function* () {
|
|
1443
|
-
yield this.writeProtocolV2Frame(transport$1, frame, {
|
|
1444
|
-
highVolume: highVolumeWrite,
|
|
1445
|
-
});
|
|
1446
|
-
}),
|
|
1447
|
-
readFrame: () => __awaiter(this, void 0, void 0, function* () {
|
|
1448
|
-
const rxFrame = yield this.readProtocolV2Frame(uuid);
|
|
1449
|
-
if (!(rxFrame instanceof Uint8Array)) {
|
|
1450
|
-
throw new Error('Protocol V2 response is not Uint8Array');
|
|
1451
|
-
}
|
|
1452
|
-
return rxFrame;
|
|
1453
|
-
}),
|
|
1454
|
-
logger: Log,
|
|
1455
|
-
logPrefix: 'ProtocolV2 RN-BLE',
|
|
1456
|
-
createTimeoutError: (_messageName, timeout) => hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleTimeoutError, `BLE response timeout after ${timeout}ms for ${name}`),
|
|
1457
|
-
});
|
|
1458
|
-
const result = yield session.call(name, data, callOptions);
|
|
1459
|
-
completed = true;
|
|
1460
|
-
return result;
|
|
1461
|
-
}
|
|
1462
|
-
catch (e) {
|
|
1463
|
-
if (this.isActiveProtocolV2Call(uuid, callToken)) {
|
|
1464
|
-
(_c = this.protocolV2Assemblers.get(uuid)) === null || _c === void 0 ? void 0 : _c.reset();
|
|
1465
|
-
this.resetProtocolV2Frames(uuid);
|
|
1466
|
-
}
|
|
1467
|
-
Log === null || Log === void 0 ? void 0 : Log.error('[ReactNativeBleTransport] Protocol V2 call error:', e);
|
|
1468
|
-
throw e;
|
|
1469
|
-
}
|
|
1470
|
-
finally {
|
|
1471
|
-
if (this.isActiveProtocolV2Call(uuid, callToken)) {
|
|
1472
|
-
if (!completed) {
|
|
1473
|
-
(_d = this.protocolV2Assemblers.get(uuid)) === null || _d === void 0 ? void 0 : _d.reset();
|
|
1474
|
-
}
|
|
1475
|
-
this.resetProtocolV2Frames(uuid);
|
|
1476
|
-
this.activeProtocolV2Call = null;
|
|
1477
|
-
}
|
|
1478
|
-
if (this.runPromise === runPromise) {
|
|
1479
|
-
this.runPromise = null;
|
|
1480
|
-
}
|
|
1481
|
-
}
|
|
1482
|
-
});
|
|
1483
|
-
}
|
|
1484
|
-
getProtocolType(path) {
|
|
1485
|
-
return this.deviceProtocol.get(path);
|
|
1486
|
-
}
|
|
1487
951
|
}
|
|
1488
952
|
|
|
1489
|
-
exports
|
|
1490
|
-
exports["default"] = ReactNativeBleTransport;
|
|
1491
|
-
exports.getProtocolV2BleTuning = getProtocolV2BleTuning;
|
|
1492
|
-
exports.resetProtocolV2BleTuning = resetProtocolV2BleTuning;
|
|
953
|
+
module.exports = ReactNativeBleTransport;
|