@onekeyfe/hd-transport-react-native 1.0.20-alpha.0 → 1.0.20-alpha.1

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.
@@ -6,6 +6,9 @@ export default class BleTransport {
6
6
  writeCharacteristic: Characteristic;
7
7
  notifyCharacteristic: Characteristic;
8
8
  nofitySubscription?: () => void;
9
+ static MAX_RETRIES: number;
10
+ static RETRY_DELAY: number;
9
11
  constructor(device: Device, writeCharacteristic: Characteristic, notifyCharacteristic: Characteristic);
12
+ writeWithRetry(data: string, retryCount?: number): Promise<void>;
10
13
  }
11
14
  //# sourceMappingURL=BleTransport.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"BleTransport.d.ts","sourceRoot":"","sources":["../src/BleTransport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAExE,MAAM,CAAC,OAAO,OAAO,YAAY;IAC/B,EAAE,EAAE,MAAM,CAAC;IAEX,MAAM,EAAE,MAAM,CAAC;IAEf,OAAO,SAAM;IAEb,mBAAmB,EAAE,cAAc,CAAC;IAEpC,oBAAoB,EAAE,cAAc,CAAC;IAErC,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;gBAG9B,MAAM,EAAE,MAAM,EACd,mBAAmB,EAAE,cAAc,EACnC,oBAAoB,EAAE,cAAc;CAQvC"}
1
+ {"version":3,"file":"BleTransport.d.ts","sourceRoot":"","sources":["../src/BleTransport.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,cAAc,EAAgB,MAAM,gCAAgC,CAAC;AAMtF,MAAM,CAAC,OAAO,OAAO,YAAY;IAC/B,EAAE,EAAE,MAAM,CAAC;IAEX,MAAM,EAAE,MAAM,CAAC;IAEf,OAAO,SAAM;IAEb,mBAAmB,EAAE,cAAc,CAAC;IAEpC,oBAAoB,EAAE,cAAc,CAAC;IAErC,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;IAEhC,MAAM,CAAC,WAAW,SAAM;IAExB,MAAM,CAAC,WAAW,SAAQ;gBAGxB,MAAM,EAAE,MAAM,EACd,mBAAmB,EAAE,cAAc,EACnC,oBAAoB,EAAE,cAAc;IAehC,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,SAA2B,GAAG,OAAO,CAAC,IAAI,CAAC;CA2BzF"}
package/dist/index.d.ts CHANGED
@@ -32,7 +32,7 @@ declare class ReactNativeBleTransport {
32
32
  }>;
33
33
  _monitorCharacteristic(characteristic: Characteristic): () => void;
34
34
  release(uuid: string): Promise<boolean>;
35
- call(uuid: string, name: string, data: Record<string, unknown>): Promise<transport.MessageFromOneKey | undefined>;
35
+ call(uuid: string, name: string, data: Record<string, unknown>): Promise<transport.MessageFromOneKey>;
36
36
  stop(): void;
37
37
  cancel(): void;
38
38
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EACL,UAAU,IAAI,aAAa,EAC3B,MAAM,EAEN,cAAc,EAEf,MAAM,gCAAgC,CAAC;AAExC,OAAO,SAAkD,MAAM,wBAAwB,CAAC;AACxF,OAAO,EAAkB,QAAQ,EAA6B,MAAM,qBAAqB,CAAC;AAC1F,OAAO,KAAK,YAAY,MAAM,QAAQ,CAAC;AAavC,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAoBjE,MAAM,CAAC,OAAO,OAAO,uBAAuB;IAC1C,aAAa,EAAE,aAAa,GAAG,SAAS,CAAC;IAEzC,SAAS,EAAE,UAAU,CAAC,OAAO,SAAS,CAAC,cAAc,CAAC,GAAG,SAAS,CAAC;IAEnE,UAAU,UAAS;IAEnB,OAAO,UAAS;IAEhB,WAAW,SAAQ;IAEnB,UAAU,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAI,CAAQ;IAExC,GAAG,CAAC,EAAE,GAAG,CAAC;IAEV,OAAO,CAAC,EAAE,YAAY,CAAC;gBAEX,OAAO,EAAE,gBAAgB;IAIrC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,YAAY;IAKvC,SAAS,CAAC,UAAU,EAAE,GAAG;IAMzB,MAAM;IAIN,aAAa,IAAI,OAAO,CAAC,aAAa,CAAC;IAYjC,SAAS;IA6FT,OAAO,CAAC,KAAK,EAAE,eAAe;;;IA2MpC,sBAAsB,CAAC,cAAc,EAAE,cAAc;IAkF/C,OAAO,CAAC,IAAI,EAAE,MAAM;IAepB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IA+FpE,IAAI;IAIJ,MAAM;CAOP"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EACL,UAAU,IAAI,aAAa,EAC3B,MAAM,EAEN,cAAc,EAEf,MAAM,gCAAgC,CAAC;AAExC,OAAO,SAAkD,MAAM,wBAAwB,CAAC;AACxF,OAAO,EAAkB,QAAQ,EAA6B,MAAM,qBAAqB,CAAC;AAC1F,OAAO,KAAK,YAAY,MAAM,QAAQ,CAAC;AAavC,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAoBjE,MAAM,CAAC,OAAO,OAAO,uBAAuB;IAC1C,aAAa,EAAE,aAAa,GAAG,SAAS,CAAC;IAEzC,SAAS,EAAE,UAAU,CAAC,OAAO,SAAS,CAAC,cAAc,CAAC,GAAG,SAAS,CAAC;IAEnE,UAAU,UAAS;IAEnB,OAAO,UAAS;IAEhB,WAAW,SAAQ;IAEnB,UAAU,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAI,CAAQ;IAExC,GAAG,CAAC,EAAE,GAAG,CAAC;IAEV,OAAO,CAAC,EAAE,YAAY,CAAC;gBAEX,OAAO,EAAE,gBAAgB;IAIrC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,YAAY;IAKvC,SAAS,CAAC,UAAU,EAAE,GAAG;IAMzB,MAAM;IAIN,aAAa,IAAI,OAAO,CAAC,aAAa,CAAC;IAYjC,SAAS;IA6FT,OAAO,CAAC,KAAK,EAAE,eAAe;;;IAkNpC,sBAAsB,CAAC,cAAc,EAAE,cAAc;IAsF/C,OAAO,CAAC,IAAI,EAAE,MAAM;IAepB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAwHpE,IAAI;IAIJ,MAAM;CAOP"}
package/dist/index.js CHANGED
@@ -7,6 +7,7 @@ var ByteBuffer = require('bytebuffer');
7
7
  var transport = require('@onekeyfe/hd-transport');
8
8
  var hdShared = require('@onekeyfe/hd-shared');
9
9
  var BleManager = require('react-native-ble-manager');
10
+ var hdCore = require('@onekeyfe/hd-core');
10
11
 
11
12
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
12
13
 
@@ -158,6 +159,7 @@ const isHeaderChunk = (chunk) => {
158
159
  return false;
159
160
  };
160
161
 
162
+ const Log = hdCore.getLogger(hdCore.LoggerNames.HdBleTransport);
161
163
  class BleTransport {
162
164
  constructor(device, writeCharacteristic, notifyCharacteristic) {
163
165
  this.mtuSize = 20;
@@ -167,7 +169,37 @@ class BleTransport {
167
169
  this.notifyCharacteristic = notifyCharacteristic;
168
170
  console.log(`BleTransport(${String(this.id)}) new instance`);
169
171
  }
172
+ writeWithRetry(data, retryCount = BleTransport.MAX_RETRIES) {
173
+ return __awaiter(this, void 0, void 0, function* () {
174
+ try {
175
+ yield this.writeCharacteristic.writeWithoutResponse(data);
176
+ }
177
+ catch (error) {
178
+ Log === null || Log === void 0 ? void 0 : Log.debug(`Write retry attempt ${BleTransport.MAX_RETRIES - retryCount + 1}, error: ${error}`);
179
+ if (retryCount > 0) {
180
+ yield hdCore.wait(BleTransport.RETRY_DELAY);
181
+ if (error.errorCode === reactNativeBlePlx.BleErrorCode.DeviceDisconnected ||
182
+ error.errorCode === reactNativeBlePlx.BleErrorCode.CharacteristicNotFound) {
183
+ try {
184
+ yield this.device.connect();
185
+ yield this.device.discoverAllServicesAndCharacteristics();
186
+ }
187
+ catch (e) {
188
+ Log === null || Log === void 0 ? void 0 : Log.debug(`Connect or discoverAllServicesAndCharacteristics error: ${e}`);
189
+ }
190
+ }
191
+ else {
192
+ Log === null || Log === void 0 ? void 0 : Log.debug(`writeCharacteristic error: ${error}`);
193
+ }
194
+ return this.writeWithRetry(data, retryCount - 1);
195
+ }
196
+ throw error;
197
+ }
198
+ });
199
+ }
170
200
  }
201
+ BleTransport.MAX_RETRIES = 10;
202
+ BleTransport.RETRY_DELAY = 2000;
171
203
 
172
204
  const { check, buildBuffers, receiveOne, parseConfigure } = transport__default["default"];
173
205
  const transportCache = {};
@@ -447,14 +479,22 @@ class ReactNativeBleTransport {
447
479
  });
448
480
  const disconnectSubscription = device.onDisconnected(() => {
449
481
  var _a;
450
- this.Log.debug('device disconnect: ', device === null || device === void 0 ? void 0 : device.id);
451
- (_a = this.emitter) === null || _a === void 0 ? void 0 : _a.emit('device-disconnect', {
452
- name: device === null || device === void 0 ? void 0 : device.name,
453
- id: device === null || device === void 0 ? void 0 : device.id,
454
- connectId: device === null || device === void 0 ? void 0 : device.id,
455
- });
456
- this.release(uuid);
457
- disconnectSubscription === null || disconnectSubscription === void 0 ? void 0 : disconnectSubscription.remove();
482
+ try {
483
+ this.Log.debug('device disconnect: ', device === null || device === void 0 ? void 0 : device.id);
484
+ (_a = this.emitter) === null || _a === void 0 ? void 0 : _a.emit('device-disconnect', {
485
+ name: device === null || device === void 0 ? void 0 : device.name,
486
+ id: device === null || device === void 0 ? void 0 : device.id,
487
+ connectId: device === null || device === void 0 ? void 0 : device.id,
488
+ });
489
+ if (this.runPromise) {
490
+ this.runPromise.reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleConnectedError));
491
+ }
492
+ }
493
+ finally {
494
+ this.runPromise = null;
495
+ this.release(uuid);
496
+ disconnectSubscription === null || disconnectSubscription === void 0 ? void 0 : disconnectSubscription.remove();
497
+ }
458
498
  });
459
499
  return { uuid };
460
500
  });
@@ -465,24 +505,29 @@ class ReactNativeBleTransport {
465
505
  const subscription = characteristic.monitor((error, c) => {
466
506
  var _a, _b, _c, _d, _e, _f, _g, _h, _j;
467
507
  if (error) {
468
- this.Log.debug(`error monitor ${characteristic.uuid}, deviceId: ${characteristic.deviceID}: ${error}`);
469
- if (this.runPromise) {
470
- let ERROR = hdShared.HardwareErrorCode.BleCharacteristicNotifyError;
471
- if ((_a = error.reason) === null || _a === void 0 ? void 0 : _a.includes('The connection has timed out unexpectedly')) {
472
- ERROR = hdShared.HardwareErrorCode.BleTimeoutError;
473
- }
474
- if ((_b = error.reason) === null || _b === void 0 ? void 0 : _b.includes('Encryption is insufficient')) {
475
- ERROR = hdShared.HardwareErrorCode.BleDeviceBondError;
476
- }
477
- if (((_c = error.reason) === null || _c === void 0 ? void 0 : _c.includes('Cannot write client characteristic config descriptor')) ||
478
- ((_d = error.reason) === null || _d === void 0 ? void 0 : _d.includes('Cannot find client characteristic config descriptor')) ||
479
- ((_e = error.reason) === null || _e === void 0 ? void 0 : _e.includes('The handle is invalid'))) {
480
- this.runPromise.reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleCharacteristicNotifyChangeFailure, (_f = error.message) !== null && _f !== void 0 ? _f : error.reason));
481
- this.Log.debug(`${hdShared.HardwareErrorCode.BleCharacteristicNotifyChangeFailure} ${error.message} ${error.reason}`);
482
- return;
508
+ try {
509
+ this.Log.debug(`error monitor ${characteristic.uuid}, deviceId: ${characteristic.deviceID}: ${error}`);
510
+ if (this.runPromise) {
511
+ let ERROR = hdShared.HardwareErrorCode.BleCharacteristicNotifyError;
512
+ if ((_a = error.reason) === null || _a === void 0 ? void 0 : _a.includes('The connection has timed out unexpectedly')) {
513
+ ERROR = hdShared.HardwareErrorCode.BleTimeoutError;
514
+ }
515
+ if ((_b = error.reason) === null || _b === void 0 ? void 0 : _b.includes('Encryption is insufficient')) {
516
+ ERROR = hdShared.HardwareErrorCode.BleDeviceBondError;
517
+ }
518
+ if (((_c = error.reason) === null || _c === void 0 ? void 0 : _c.includes('Cannot write client characteristic config descriptor')) ||
519
+ ((_d = error.reason) === null || _d === void 0 ? void 0 : _d.includes('Cannot find client characteristic config descriptor')) ||
520
+ ((_e = error.reason) === null || _e === void 0 ? void 0 : _e.includes('The handle is invalid'))) {
521
+ this.runPromise.reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleCharacteristicNotifyChangeFailure, (_f = error.message) !== null && _f !== void 0 ? _f : error.reason));
522
+ this.Log.debug(`${hdShared.HardwareErrorCode.BleCharacteristicNotifyChangeFailure} ${error.message} ${error.reason}`);
523
+ return;
524
+ }
525
+ this.runPromise.reject(hdShared.ERRORS.TypedError(ERROR, (_g = error.reason) !== null && _g !== void 0 ? _g : error.message));
526
+ this.Log.debug(': monitor notify error, and has unreleased Promise');
483
527
  }
484
- this.runPromise.reject(hdShared.ERRORS.TypedError(ERROR, (_g = error.reason) !== null && _g !== void 0 ? _g : error.message));
485
- this.Log.debug(': monitor notify error, and has unreleased Promise');
528
+ }
529
+ finally {
530
+ this.runPromise = null;
486
531
  }
487
532
  return;
488
533
  }
@@ -557,27 +602,42 @@ class ReactNativeBleTransport {
557
602
  this.Log.debug('transport-react-native', 'call-', ' name: ', name, ' data: ', data);
558
603
  }
559
604
  const buffers = buildBuffers(messages, name, data);
560
- if (name === 'FirmwareUpload' || name === 'EmmcFileWrite') {
561
- const packetCapacity = reactNative.Platform.OS === 'ios' ? IOS_PACKET_LENGTH : ANDROID_PACKET_LENGTH;
562
- let index = 0;
563
- let chunk = ByteBuffer__default["default"].allocate(packetCapacity);
564
- while (index < buffers.length) {
565
- const buffer = buffers[index].toBuffer();
566
- chunk.append(buffer);
567
- index += 1;
568
- if (chunk.offset === packetCapacity || index >= buffers.length) {
569
- chunk.reset();
570
- try {
571
- yield transport$1.writeCharacteristic.writeWithoutResponse(chunk.toString('base64'));
572
- chunk = ByteBuffer__default["default"].allocate(packetCapacity);
573
- }
574
- catch (e) {
575
- this.runPromise = null;
576
- this.Log.error('writeCharacteristic write error: ', e);
577
- return;
605
+ function writeChunkedData(buffers, writeFunction, onError) {
606
+ return __awaiter(this, void 0, void 0, function* () {
607
+ const packetCapacity = reactNative.Platform.OS === 'ios' ? IOS_PACKET_LENGTH : ANDROID_PACKET_LENGTH;
608
+ let index = 0;
609
+ let chunk = ByteBuffer__default["default"].allocate(packetCapacity);
610
+ while (index < buffers.length) {
611
+ const buffer = buffers[index].toBuffer();
612
+ chunk.append(buffer);
613
+ index += 1;
614
+ if (chunk.offset === packetCapacity || index >= buffers.length) {
615
+ chunk.reset();
616
+ try {
617
+ yield writeFunction(chunk.toString('base64'));
618
+ chunk = ByteBuffer__default["default"].allocate(packetCapacity);
619
+ }
620
+ catch (e) {
621
+ onError(e);
622
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleWriteCharacteristicError);
623
+ }
578
624
  }
579
625
  }
580
- }
626
+ });
627
+ }
628
+ if (name === 'EmmcFileWrite') {
629
+ yield writeChunkedData(buffers, data => transport$1.writeWithRetry(data), e => {
630
+ this.runPromise = null;
631
+ this.Log.error('writeCharacteristic write error: ', e);
632
+ });
633
+ }
634
+ else if (name === 'FirmwareUpload') {
635
+ yield writeChunkedData(buffers, (data) => __awaiter(this, void 0, void 0, function* () {
636
+ yield transport$1.writeCharacteristic.writeWithoutResponse(data);
637
+ }), e => {
638
+ this.runPromise = null;
639
+ this.Log.error('writeCharacteristic write error: ', e);
640
+ });
581
641
  }
582
642
  else {
583
643
  for (const o of buffers) {
@@ -591,10 +651,12 @@ class ReactNativeBleTransport {
591
651
  if (e.errorCode === reactNativeBlePlx.BleErrorCode.DeviceDisconnected) {
592
652
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceNotBonded);
593
653
  }
594
- if (e.errorCode === reactNativeBlePlx.BleErrorCode.OperationStartFailed) {
654
+ else if (e.errorCode === reactNativeBlePlx.BleErrorCode.OperationStartFailed) {
595
655
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleWriteCharacteristicError, e.reason);
596
656
  }
597
- return;
657
+ else {
658
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleWriteCharacteristicError);
659
+ }
598
660
  }
599
661
  }
600
662
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/hd-transport-react-native",
3
- "version": "1.0.20-alpha.0",
3
+ "version": "1.0.20-alpha.1",
4
4
  "homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -19,10 +19,10 @@
19
19
  "lint:fix": "eslint . --fix"
20
20
  },
21
21
  "dependencies": {
22
- "@onekeyfe/hd-shared": "^1.0.20-alpha.0",
23
- "@onekeyfe/hd-transport": "^1.0.20-alpha.0",
22
+ "@onekeyfe/hd-shared": "^1.0.20-alpha.1",
23
+ "@onekeyfe/hd-transport": "^1.0.20-alpha.1",
24
24
  "@onekeyfe/react-native-ble-plx": "3.0.1",
25
25
  "react-native-ble-manager": "^8.1.0"
26
26
  },
27
- "gitHead": "cad00ee80af662e061d875d3e3e3e46f9658337f"
27
+ "gitHead": "d80a8d0a75952c3490c5d88c79448177ff492f12"
28
28
  }
@@ -1,4 +1,8 @@
1
- import { Device, Characteristic } from '@onekeyfe/react-native-ble-plx';
1
+ import { Device, Characteristic, BleErrorCode } from '@onekeyfe/react-native-ble-plx';
2
+ import { getLogger, LoggerNames, wait } from '@onekeyfe/hd-core';
3
+ // import { wait } from '@onekeyfe/hd-core/src/utils';
4
+
5
+ const Log = getLogger(LoggerNames.HdBleTransport);
2
6
 
3
7
  export default class BleTransport {
4
8
  id: string;
@@ -13,6 +17,10 @@ export default class BleTransport {
13
17
 
14
18
  nofitySubscription?: () => void;
15
19
 
20
+ static MAX_RETRIES = 10;
21
+
22
+ static RETRY_DELAY = 2000;
23
+
16
24
  constructor(
17
25
  device: Device,
18
26
  writeCharacteristic: Characteristic,
@@ -24,4 +32,38 @@ export default class BleTransport {
24
32
  this.notifyCharacteristic = notifyCharacteristic;
25
33
  console.log(`BleTransport(${String(this.id)}) new instance`);
26
34
  }
35
+
36
+ /**
37
+ * @description only for pro / touch , while upgrade firmware
38
+ * @param data
39
+ * @param retryCount
40
+ * @returns
41
+ */
42
+ async writeWithRetry(data: string, retryCount = BleTransport.MAX_RETRIES): Promise<void> {
43
+ try {
44
+ await this.writeCharacteristic.writeWithoutResponse(data);
45
+ } catch (error) {
46
+ Log?.debug(
47
+ `Write retry attempt ${BleTransport.MAX_RETRIES - retryCount + 1}, error: ${error}`
48
+ );
49
+ if (retryCount > 0) {
50
+ await wait(BleTransport.RETRY_DELAY);
51
+ if (
52
+ error.errorCode === BleErrorCode.DeviceDisconnected ||
53
+ error.errorCode === BleErrorCode.CharacteristicNotFound
54
+ ) {
55
+ try {
56
+ await this.device.connect();
57
+ await this.device.discoverAllServicesAndCharacteristics();
58
+ } catch (e) {
59
+ Log?.debug(`Connect or discoverAllServicesAndCharacteristics error: ${e}`);
60
+ }
61
+ } else {
62
+ Log?.debug(`writeCharacteristic error: ${error}`);
63
+ }
64
+ return this.writeWithRetry(data, retryCount - 1);
65
+ }
66
+ throw error;
67
+ }
68
+ }
27
69
  }
package/src/index.ts CHANGED
@@ -374,14 +374,21 @@ export default class ReactNativeBleTransport {
374
374
  });
375
375
 
376
376
  const disconnectSubscription = device.onDisconnected(() => {
377
- this.Log.debug('device disconnect: ', device?.id);
378
- this.emitter?.emit('device-disconnect', {
379
- name: device?.name,
380
- id: device?.id,
381
- connectId: device?.id,
382
- });
383
- this.release(uuid);
384
- disconnectSubscription?.remove();
377
+ try {
378
+ this.Log.debug('device disconnect: ', device?.id);
379
+ this.emitter?.emit('device-disconnect', {
380
+ name: device?.name,
381
+ id: device?.id,
382
+ connectId: device?.id,
383
+ });
384
+ if (this.runPromise) {
385
+ this.runPromise.reject(ERRORS.TypedError(HardwareErrorCode.BleConnectedError));
386
+ }
387
+ } finally {
388
+ this.runPromise = null;
389
+ this.release(uuid);
390
+ disconnectSubscription?.remove();
391
+ }
385
392
  });
386
393
 
387
394
  return { uuid };
@@ -392,41 +399,45 @@ export default class ReactNativeBleTransport {
392
399
  let buffer: any[] = [];
393
400
  const subscription = characteristic.monitor((error, c) => {
394
401
  if (error) {
395
- this.Log.debug(
396
- `error monitor ${characteristic.uuid}, deviceId: ${characteristic.deviceID}: ${
397
- error as unknown as string
398
- }`
399
- );
400
- if (this.runPromise) {
401
- let ERROR:
402
- | typeof HardwareErrorCode.BleDeviceBondError
403
- | typeof HardwareErrorCode.BleCharacteristicNotifyError
404
- | typeof HardwareErrorCode.BleTimeoutError =
405
- HardwareErrorCode.BleCharacteristicNotifyError;
406
- if (error.reason?.includes('The connection has timed out unexpectedly')) {
407
- ERROR = HardwareErrorCode.BleTimeoutError;
408
- }
409
- if (error.reason?.includes('Encryption is insufficient')) {
410
- ERROR = HardwareErrorCode.BleDeviceBondError;
411
- }
412
- if (
413
- error.reason?.includes('Cannot write client characteristic config descriptor') ||
414
- error.reason?.includes('Cannot find client characteristic config descriptor') ||
415
- error.reason?.includes('The handle is invalid')
416
- ) {
417
- this.runPromise.reject(
418
- ERRORS.TypedError(
419
- HardwareErrorCode.BleCharacteristicNotifyChangeFailure,
420
- error.message ?? error.reason
421
- )
422
- );
423
- this.Log.debug(
424
- `${HardwareErrorCode.BleCharacteristicNotifyChangeFailure} ${error.message} ${error.reason}`
425
- );
426
- return;
402
+ try {
403
+ this.Log.debug(
404
+ `error monitor ${characteristic.uuid}, deviceId: ${characteristic.deviceID}: ${
405
+ error as unknown as string
406
+ }`
407
+ );
408
+ if (this.runPromise) {
409
+ let ERROR:
410
+ | typeof HardwareErrorCode.BleDeviceBondError
411
+ | typeof HardwareErrorCode.BleCharacteristicNotifyError
412
+ | typeof HardwareErrorCode.BleTimeoutError =
413
+ HardwareErrorCode.BleCharacteristicNotifyError;
414
+ if (error.reason?.includes('The connection has timed out unexpectedly')) {
415
+ ERROR = HardwareErrorCode.BleTimeoutError;
416
+ }
417
+ if (error.reason?.includes('Encryption is insufficient')) {
418
+ ERROR = HardwareErrorCode.BleDeviceBondError;
419
+ }
420
+ if (
421
+ error.reason?.includes('Cannot write client characteristic config descriptor') ||
422
+ error.reason?.includes('Cannot find client characteristic config descriptor') ||
423
+ error.reason?.includes('The handle is invalid')
424
+ ) {
425
+ this.runPromise.reject(
426
+ ERRORS.TypedError(
427
+ HardwareErrorCode.BleCharacteristicNotifyChangeFailure,
428
+ error.message ?? error.reason
429
+ )
430
+ );
431
+ this.Log.debug(
432
+ `${HardwareErrorCode.BleCharacteristicNotifyChangeFailure} ${error.message} ${error.reason}`
433
+ );
434
+ return;
435
+ }
436
+ this.runPromise.reject(ERRORS.TypedError(ERROR, error.reason ?? error.message));
437
+ this.Log.debug(': monitor notify error, and has unreleased Promise');
427
438
  }
428
- this.runPromise.reject(ERRORS.TypedError(ERROR, error.reason ?? error.message));
429
- this.Log.debug(': monitor notify error, and has unreleased Promise');
439
+ } finally {
440
+ this.runPromise = null;
430
441
  }
431
442
  return;
432
443
  }
@@ -516,30 +527,55 @@ export default class ReactNativeBleTransport {
516
527
  this.Log.debug('transport-react-native', 'call-', ' name: ', name, ' data: ', data);
517
528
  }
518
529
 
519
- const buffers = buildBuffers(messages, name, data);
530
+ const buffers = buildBuffers(messages, name, data) as Array<ByteBuffer>;
520
531
 
521
- if (name === 'FirmwareUpload' || name === 'EmmcFileWrite') {
532
+ async function writeChunkedData(
533
+ buffers: ByteBuffer[],
534
+ writeFunction: (data: string) => Promise<void>,
535
+ onError: (e: any) => void
536
+ ) {
522
537
  const packetCapacity = Platform.OS === 'ios' ? IOS_PACKET_LENGTH : ANDROID_PACKET_LENGTH;
523
538
  let index = 0;
524
539
  let chunk = ByteBuffer.allocate(packetCapacity);
540
+
525
541
  while (index < buffers.length) {
526
542
  const buffer = buffers[index].toBuffer();
527
543
  chunk.append(buffer);
528
544
  index += 1;
545
+
529
546
  if (chunk.offset === packetCapacity || index >= buffers.length) {
530
547
  chunk.reset();
531
- // Upgrading Packet Logs, Too much content to ignore
532
- // this.Log.debug('send more packet hex strting: ', chunk.toString('hex'));
533
548
  try {
534
- await transport.writeCharacteristic.writeWithoutResponse(chunk.toString('base64'));
549
+ await writeFunction(chunk.toString('base64'));
535
550
  chunk = ByteBuffer.allocate(packetCapacity);
536
551
  } catch (e) {
537
- this.runPromise = null;
538
- this.Log.error('writeCharacteristic write error: ', e);
539
- return;
552
+ onError(e);
553
+ throw ERRORS.TypedError(HardwareErrorCode.BleWriteCharacteristicError);
540
554
  }
541
555
  }
542
556
  }
557
+ }
558
+
559
+ if (name === 'EmmcFileWrite') {
560
+ await writeChunkedData(
561
+ buffers,
562
+ data => transport.writeWithRetry(data),
563
+ e => {
564
+ this.runPromise = null;
565
+ this.Log.error('writeCharacteristic write error: ', e);
566
+ }
567
+ );
568
+ } else if (name === 'FirmwareUpload') {
569
+ await writeChunkedData(
570
+ buffers,
571
+ async data => {
572
+ await transport.writeCharacteristic.writeWithoutResponse(data);
573
+ },
574
+ e => {
575
+ this.runPromise = null;
576
+ this.Log.error('writeCharacteristic write error: ', e);
577
+ }
578
+ );
543
579
  } else {
544
580
  for (const o of buffers) {
545
581
  const outData = o.toString('base64');
@@ -552,11 +588,11 @@ export default class ReactNativeBleTransport {
552
588
  this.runPromise = null;
553
589
  if (e.errorCode === BleErrorCode.DeviceDisconnected) {
554
590
  throw ERRORS.TypedError(HardwareErrorCode.BleDeviceNotBonded);
555
- }
556
- if (e.errorCode === BleErrorCode.OperationStartFailed) {
591
+ } else if (e.errorCode === BleErrorCode.OperationStartFailed) {
557
592
  throw ERRORS.TypedError(HardwareErrorCode.BleWriteCharacteristicError, e.reason);
593
+ } else {
594
+ throw ERRORS.TypedError(HardwareErrorCode.BleWriteCharacteristicError);
558
595
  }
559
- return;
560
596
  }
561
597
  }
562
598
  }