@onekeyfe/hd-transport-react-native 1.1.22 → 1.1.23

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.
@@ -1,4 +1,4 @@
1
- import type { Characteristic, Device } from 'react-native-ble-plx';
1
+ import type { Characteristic, Device, Subscription } from 'react-native-ble-plx';
2
2
  export default class BleTransport {
3
3
  id: string;
4
4
  name: string;
@@ -6,7 +6,8 @@ export default class BleTransport {
6
6
  mtuSize: number;
7
7
  writeCharacteristic: Characteristic;
8
8
  notifyCharacteristic: Characteristic;
9
- nofitySubscription?: () => void;
9
+ notifySubscription?: Subscription;
10
+ disconnectSubscription?: Subscription;
10
11
  static MAX_RETRIES: number;
11
12
  static RETRY_DELAY: number;
12
13
  constructor(device: Device, writeCharacteristic: Characteristic, notifyCharacteristic: Characteristic);
@@ -1 +1 @@
1
- {"version":3,"file":"BleTransport.d.ts","sourceRoot":"","sources":["../src/BleTransport.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAKnE,MAAM,CAAC,OAAO,OAAO,YAAY;IAC/B,EAAE,EAAE,MAAM,CAAC;IAEX,IAAI,SAA6B;IAEjC,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,SAAK;IAEvB,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"}
1
+ {"version":3,"file":"BleTransport.d.ts","sourceRoot":"","sources":["../src/BleTransport.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAKjF,MAAM,CAAC,OAAO,OAAO,YAAY;IAC/B,EAAE,EAAE,MAAM,CAAC;IAEX,IAAI,SAA6B;IAEjC,MAAM,EAAE,MAAM,CAAC;IAEf,OAAO,SAAM;IAEb,mBAAmB,EAAE,cAAc,CAAC;IAEpC,oBAAoB,EAAE,cAAc,CAAC;IAErC,kBAAkB,CAAC,EAAE,YAAY,CAAC;IAElC,sBAAsB,CAAC,EAAE,YAAY,CAAC;IAEtC,MAAM,CAAC,WAAW,SAAK;IAEvB,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
@@ -1,6 +1,6 @@
1
1
  import * as transport from '@onekeyfe/hd-transport';
2
2
  import transport__default, { OneKeyDeviceInfoBase } from '@onekeyfe/hd-transport';
3
- import { Device, BleManager, Characteristic } from 'react-native-ble-plx';
3
+ import { Device, BleManager, Characteristic, Subscription } from 'react-native-ble-plx';
4
4
  import { Deferred } from '@onekeyfe/hd-shared';
5
5
  import EventEmitter from 'events';
6
6
 
@@ -21,10 +21,9 @@ declare class ReactNativeBleTransport {
21
21
  stopped: boolean;
22
22
  scanTimeout: number;
23
23
  runPromise: Deferred<any> | null;
24
- Log?: any;
25
24
  emitter?: EventEmitter;
26
25
  constructor(options: TransportOptions);
27
- init(logger: any, emitter: EventEmitter): void;
26
+ init(_logger: any, emitter: EventEmitter): void;
28
27
  configure(signedData: any): void;
29
28
  listen(): void;
30
29
  getPlxManager(): Promise<BleManager>;
@@ -32,7 +31,7 @@ declare class ReactNativeBleTransport {
32
31
  acquire(input: BleAcquireInput): Promise<{
33
32
  uuid: string;
34
33
  }>;
35
- _monitorCharacteristic(characteristic: Characteristic, uuid: string): () => void;
34
+ _monitorCharacteristic(characteristic: Characteristic, uuid: string): Subscription;
36
35
  release(uuid: string): Promise<boolean>;
37
36
  post(session: string, name: string, data: Record<string, unknown>): Promise<void>;
38
37
  call(uuid: string, name: string, data: Record<string, unknown>): Promise<transport.MessageFromOneKey>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAIL,UAAU,IAAI,aAAa,EAE5B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,SAAS,EAAE,EAGhB,KAAK,oBAAoB,EAC1B,MAAM,wBAAwB,CAAC;AAehC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,KAAK,YAAY,MAAM,QAAQ,CAAC;AACvC,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAYjE,MAAM,MAAM,aAAa,GAAG,oBAAoB,GAAG,MAAM,CAAC;AA0C1D,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,IAAI,SAA6B;IAEjC,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;IAWjC,SAAS;IA6FT,OAAO,CAAC,KAAK,EAAE,eAAe;;;IAqNpC,sBAAsB,CAAC,cAAc,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM;IAkF7D,OAAO,CAAC,IAAI,EAAE,MAAM;IAepB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAIjE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IA2HpE,IAAI;IAIE,UAAU,CAAC,OAAO,EAAE,MAAM;IA6DhC,MAAM;CAOP"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAIL,UAAU,IAAI,aAAa,EAE5B,MAAM,sBAAsB,CAAC;AAE9B,OAAO,SAAS,EAAE,EAGhB,KAAK,oBAAoB,EAC1B,MAAM,wBAAwB,CAAC;AAgBhC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACjF,OAAO,KAAK,YAAY,MAAM,QAAQ,CAAC;AACvC,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAcjE,MAAM,MAAM,aAAa,GAAG,oBAAoB,GAAG,MAAM,CAAC;AA0C1D,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,IAAI,SAA6B;IAEjC,UAAU,UAAS;IAEnB,OAAO,UAAS;IAEhB,WAAW,SAAQ;IAEnB,UAAU,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAI,CAAQ;IAExC,OAAO,CAAC,EAAE,YAAY,CAAC;gBAEX,OAAO,EAAE,gBAAgB;IAIrC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,YAAY;IAIxC,SAAS,CAAC,UAAU,EAAE,GAAG;IAMzB,MAAM;IAIN,aAAa,IAAI,OAAO,CAAC,aAAa,CAAC;IAWjC,SAAS;IA6FT,OAAO,CAAC,KAAK,EAAE,eAAe;;;IAiNpC,sBAAsB,CAAC,cAAc,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,YAAY;IA+E5E,OAAO,CAAC,IAAI,EAAE,MAAM;IA4BpB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAIjE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IA2HpE,IAAI;IAIE,UAAU,CAAC,OAAO,EAAE,MAAM;IA0EhC,MAAM;CAOP"}
package/dist/index.js CHANGED
@@ -6,8 +6,8 @@ var reactNativeBlePlx = require('react-native-ble-plx');
6
6
  var ByteBuffer = require('bytebuffer');
7
7
  var transport = require('@onekeyfe/hd-transport');
8
8
  var hdShared = require('@onekeyfe/hd-shared');
9
- var BleUtils = require('@onekeyfe/react-native-ble-utils');
10
9
  var hdCore = require('@onekeyfe/hd-core');
10
+ var BleUtils = require('@onekeyfe/react-native-ble-utils');
11
11
 
12
12
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
13
13
 
@@ -168,7 +168,7 @@ const isHeaderChunk = (chunk) => {
168
168
  return false;
169
169
  };
170
170
 
171
- const Log = hdCore.getLogger(hdCore.LoggerNames.HdBleTransport);
171
+ const Log$1 = hdCore.getLogger(hdCore.LoggerNames.HdBleTransport);
172
172
  class BleTransport {
173
173
  constructor(device, writeCharacteristic, notifyCharacteristic) {
174
174
  this.name = 'ReactNativeBleTransport';
@@ -185,7 +185,7 @@ class BleTransport {
185
185
  yield this.writeCharacteristic.writeWithoutResponse(data);
186
186
  }
187
187
  catch (error) {
188
- Log === null || Log === void 0 ? void 0 : Log.debug(`Write retry attempt ${BleTransport.MAX_RETRIES - retryCount + 1}, error: ${error}`);
188
+ Log$1 === null || Log$1 === void 0 ? void 0 : Log$1.debug(`Write retry attempt ${BleTransport.MAX_RETRIES - retryCount + 1}, error: ${error}`);
189
189
  if (retryCount > 0) {
190
190
  yield hdCore.wait(BleTransport.RETRY_DELAY);
191
191
  if (error.errorCode === reactNativeBlePlx.BleErrorCode.DeviceDisconnected ||
@@ -195,11 +195,11 @@ class BleTransport {
195
195
  yield this.device.discoverAllServicesAndCharacteristics();
196
196
  }
197
197
  catch (e) {
198
- Log === null || Log === void 0 ? void 0 : Log.debug(`Connect or discoverAllServicesAndCharacteristics error: ${e}`);
198
+ Log$1 === null || Log$1 === void 0 ? void 0 : Log$1.debug(`Connect or discoverAllServicesAndCharacteristics error: ${e}`);
199
199
  }
200
200
  }
201
201
  else {
202
- Log === null || Log === void 0 ? void 0 : Log.debug(`writeCharacteristic error: ${error}`);
202
+ Log$1 === null || Log$1 === void 0 ? void 0 : Log$1.debug(`writeCharacteristic error: ${error}`);
203
203
  }
204
204
  return this.writeWithRetry(data, retryCount - 1);
205
205
  }
@@ -212,6 +212,7 @@ BleTransport.MAX_RETRIES = 5;
212
212
  BleTransport.RETRY_DELAY = 2000;
213
213
 
214
214
  const { check, buildBuffers, receiveOne, parseConfigure } = transport__default["default"];
215
+ const Log = hdCore.getLogger(hdCore.LoggerNames.HdBleTransport);
215
216
  const transportCache = {};
216
217
  let connectOptions = {
217
218
  requestMTU: 256,
@@ -255,8 +256,7 @@ class ReactNativeBleTransport {
255
256
  this.runPromise = null;
256
257
  this.scanTimeout = (_a = options.scanTimeout) !== null && _a !== void 0 ? _a : 3000;
257
258
  }
258
- init(logger, emitter) {
259
- this.Log = logger;
259
+ init(_logger, emitter) {
260
260
  this.emitter = emitter;
261
261
  }
262
262
  configure(signedData) {
@@ -281,17 +281,17 @@ class ReactNativeBleTransport {
281
281
  yield subscribeBleOn(blePlxManager);
282
282
  }
283
283
  catch (error) {
284
- this.Log.debug('subscribeBleOn error: ', error);
284
+ Log === null || Log === void 0 ? void 0 : Log.debug('subscribeBleOn error: ', error);
285
285
  reject(error);
286
286
  return;
287
287
  }
288
288
  if (reactNative.Platform.OS === 'android' && reactNative.Platform.Version >= 31) {
289
- this.Log.debug('requesting permissions, please wait...');
289
+ Log === null || Log === void 0 ? void 0 : Log.debug('requesting permissions, please wait...');
290
290
  const resultConnect = yield reactNative.PermissionsAndroid.requestMultiple([
291
291
  reactNative.PermissionsAndroid.PERMISSIONS.BLUETOOTH_CONNECT,
292
292
  reactNative.PermissionsAndroid.PERMISSIONS.BLUETOOTH_SCAN,
293
293
  ]);
294
- this.Log.debug('requesting permissions, result: ', resultConnect);
294
+ Log === null || Log === void 0 ? void 0 : Log.debug('requesting permissions, result: ', resultConnect);
295
295
  if (resultConnect[reactNative.PermissionsAndroid.PERMISSIONS.BLUETOOTH_CONNECT] !== 'granted' ||
296
296
  resultConnect[reactNative.PermissionsAndroid.PERMISSIONS.BLUETOOTH_SCAN] !== 'granted') {
297
297
  reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BlePermissionError));
@@ -303,8 +303,8 @@ class ReactNativeBleTransport {
303
303
  }, (error, device) => {
304
304
  var _a, _b;
305
305
  if (error) {
306
- this.Log.debug('ble scan manager: ', blePlxManager);
307
- this.Log.debug('ble scan error: ', error);
306
+ Log === null || Log === void 0 ? void 0 : Log.debug('ble scan manager: ', blePlxManager);
307
+ Log === null || Log === void 0 ? void 0 : Log.debug('ble scan error: ', error);
308
308
  if ([reactNativeBlePlx.BleErrorCode.BluetoothPoweredOff, reactNativeBlePlx.BleErrorCode.BluetoothInUnknownState].includes(error.errorCode)) {
309
309
  reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BlePermissionError));
310
310
  }
@@ -323,16 +323,16 @@ class ReactNativeBleTransport {
323
323
  return;
324
324
  }
325
325
  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)) {
326
- this.Log.debug('search device start ======================');
326
+ Log === null || Log === void 0 ? void 0 : Log.debug('search device start ======================');
327
327
  const { name, localName, id } = device !== null && device !== void 0 ? device : {};
328
- this.Log.debug(`device name: ${name !== null && name !== void 0 ? name : ''}\nlocalName: ${localName !== null && localName !== void 0 ? localName : ''}\nid: ${id !== null && id !== void 0 ? id : ''}`);
328
+ 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 : ''}`);
329
329
  addDevice(device);
330
- this.Log.debug('search device end ======================\n');
330
+ Log === null || Log === void 0 ? void 0 : Log.debug('search device end ======================\n');
331
331
  }
332
332
  });
333
333
  getConnectedDeviceIds(getBluetoothServiceUuids()).then(devices => {
334
334
  for (const device of devices) {
335
- this.Log.debug('search connected peripheral: ', device.id);
335
+ Log === null || Log === void 0 ? void 0 : Log.debug('search connected peripheral: ', device.id);
336
336
  addDevice(device);
337
337
  }
338
338
  });
@@ -357,19 +357,19 @@ class ReactNativeBleTransport {
357
357
  }
358
358
  let device = null;
359
359
  if (transportCache[uuid]) {
360
- this.Log.debug('transport not be released, will release: ', uuid);
360
+ Log === null || Log === void 0 ? void 0 : Log.debug('transport not be released, will release: ', uuid);
361
361
  yield this.release(uuid);
362
362
  }
363
363
  if (forceCleanRunPromise && this.runPromise) {
364
364
  this.runPromise.reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleForceCleanRunPromise));
365
- this.Log.debug('Force clean Bluetooth run promise, forceCleanRunPromise: ', forceCleanRunPromise);
365
+ Log === null || Log === void 0 ? void 0 : Log.debug('Force clean Bluetooth run promise, forceCleanRunPromise: ', forceCleanRunPromise);
366
366
  }
367
367
  const blePlxManager = yield this.getPlxManager();
368
368
  try {
369
369
  yield subscribeBleOn(blePlxManager);
370
370
  }
371
371
  catch (error) {
372
- this.Log.debug('subscribeBleOn error: ', error);
372
+ Log === null || Log === void 0 ? void 0 : Log.debug('subscribeBleOn error: ', error);
373
373
  throw error;
374
374
  }
375
375
  if (reactNative.Platform.OS === 'android') {
@@ -385,24 +385,24 @@ class ReactNativeBleTransport {
385
385
  if (!device) {
386
386
  const connectedDevice = yield blePlxManager.connectedDevices(getBluetoothServiceUuids());
387
387
  const deviceFilter = connectedDevice.filter(device => device.id === uuid);
388
- this.Log.debug(`found connected device count: ${deviceFilter.length}`);
388
+ Log === null || Log === void 0 ? void 0 : Log.debug(`found connected device count: ${deviceFilter.length}`);
389
389
  [device] = deviceFilter;
390
390
  }
391
391
  if (!device) {
392
- this.Log.debug('try to connect to device: ', uuid);
392
+ Log === null || Log === void 0 ? void 0 : Log.debug('try to connect to device: ', uuid);
393
393
  try {
394
394
  device = yield blePlxManager.connectToDevice(uuid, connectOptions);
395
395
  }
396
396
  catch (e) {
397
- this.Log.debug('try to connect to device has error: ', e);
397
+ Log === null || Log === void 0 ? void 0 : Log.debug('try to connect to device has error: ', e);
398
398
  if (e.errorCode === reactNativeBlePlx.BleErrorCode.DeviceMTUChangeFailed ||
399
399
  e.errorCode === reactNativeBlePlx.BleErrorCode.OperationCancelled) {
400
400
  connectOptions = {};
401
- this.Log.debug('first try to reconnect without params');
401
+ Log === null || Log === void 0 ? void 0 : Log.debug('first try to reconnect without params');
402
402
  device = yield blePlxManager.connectToDevice(uuid);
403
403
  }
404
404
  else if (e.errorCode === reactNativeBlePlx.BleErrorCode.DeviceAlreadyConnected) {
405
- this.Log.debug('device already connected');
405
+ Log === null || Log === void 0 ? void 0 : Log.debug('device already connected');
406
406
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleAlreadyConnected);
407
407
  }
408
408
  else {
@@ -414,23 +414,23 @@ class ReactNativeBleTransport {
414
414
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleConnectedError, 'unable to connect to device');
415
415
  }
416
416
  if (!(yield device.isConnected())) {
417
- this.Log.debug('not connected, try to connect to device: ', uuid);
417
+ Log === null || Log === void 0 ? void 0 : Log.debug('not connected, try to connect to device: ', uuid);
418
418
  try {
419
419
  yield device.connect(connectOptions);
420
420
  }
421
421
  catch (e) {
422
- this.Log.debug('not connected, try to connect to device has error: ', e);
422
+ Log === null || Log === void 0 ? void 0 : Log.debug('not connected, try to connect to device has error: ', e);
423
423
  if (e.errorCode === reactNativeBlePlx.BleErrorCode.DeviceMTUChangeFailed ||
424
424
  e.errorCode === reactNativeBlePlx.BleErrorCode.OperationCancelled) {
425
425
  connectOptions = {};
426
- this.Log.debug('second try to reconnect without params');
426
+ Log === null || Log === void 0 ? void 0 : Log.debug('second try to reconnect without params');
427
427
  try {
428
428
  yield device.connect();
429
429
  }
430
430
  catch (e) {
431
- this.Log.debug('last try to reconnect error: ', e);
431
+ Log === null || Log === void 0 ? void 0 : Log.debug('last try to reconnect error: ', e);
432
432
  if (e.errorCode === reactNativeBlePlx.BleErrorCode.OperationCancelled) {
433
- this.Log.debug('last try to reconnect');
433
+ Log === null || Log === void 0 ? void 0 : Log.debug('last try to reconnect');
434
434
  yield device.cancelConnection();
435
435
  yield device.connect();
436
436
  }
@@ -452,17 +452,17 @@ class ReactNativeBleTransport {
452
452
  break;
453
453
  }
454
454
  catch (e) {
455
- this.Log.error(e);
455
+ Log === null || Log === void 0 ? void 0 : Log.error(e);
456
456
  }
457
457
  }
458
458
  }
459
459
  if (!infos) {
460
460
  try {
461
- this.Log.debug('cancel connection when service not found');
461
+ Log === null || Log === void 0 ? void 0 : Log.debug('cancel connection when service not found');
462
462
  yield device.cancelConnection();
463
463
  }
464
464
  catch (e) {
465
- this.Log.debug('cancel connection error when service not found: ', e.message || e.reason);
465
+ Log === null || Log === void 0 ? void 0 : Log.debug('cancel connection error when service not found: ', e.message || e.reason);
466
466
  }
467
467
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleServiceNotFound);
468
468
  }
@@ -497,17 +497,17 @@ class ReactNativeBleTransport {
497
497
  }
498
498
  yield this.release(uuid);
499
499
  const transport = new BleTransport(device, writeCharacteristic, notifyCharacteristic);
500
- transport.nofitySubscription = this._monitorCharacteristic(transport.notifyCharacteristic, uuid);
500
+ transport.notifySubscription = this._monitorCharacteristic(transport.notifyCharacteristic, uuid);
501
501
  transportCache[uuid] = transport;
502
502
  (_a = this.emitter) === null || _a === void 0 ? void 0 : _a.emit('device-connect', {
503
503
  name: device.name,
504
504
  id: device.id,
505
505
  connectId: device.id,
506
506
  });
507
- const disconnectSubscription = device.onDisconnected(() => {
507
+ transport.disconnectSubscription = device.onDisconnected(() => {
508
508
  var _a;
509
509
  try {
510
- this.Log.debug('device disconnect: ', device === null || device === void 0 ? void 0 : device.id);
510
+ Log === null || Log === void 0 ? void 0 : Log.debug('device disconnect: ', device === null || device === void 0 ? void 0 : device.id);
511
511
  (_a = this.emitter) === null || _a === void 0 ? void 0 : _a.emit('device-disconnect', {
512
512
  name: device === null || device === void 0 ? void 0 : device.name,
513
513
  id: device === null || device === void 0 ? void 0 : device.id,
@@ -518,11 +518,10 @@ class ReactNativeBleTransport {
518
518
  }
519
519
  }
520
520
  catch (e) {
521
- this.Log.debug('device disconnect error: ', e);
521
+ Log === null || Log === void 0 ? void 0 : Log.debug('device disconnect error: ', e);
522
522
  }
523
523
  finally {
524
524
  this.release(uuid);
525
- disconnectSubscription === null || disconnectSubscription === void 0 ? void 0 : disconnectSubscription.remove();
526
525
  }
527
526
  });
528
527
  return { uuid };
@@ -534,7 +533,7 @@ class ReactNativeBleTransport {
534
533
  const subscription = characteristic.monitor((error, c) => {
535
534
  var _a, _b, _c, _d, _e, _f, _g, _h, _j;
536
535
  if (error) {
537
- this.Log.debug(`error monitor ${characteristic.uuid}, deviceId: ${characteristic.deviceID}: ${error}`);
536
+ Log === null || Log === void 0 ? void 0 : Log.debug(`error monitor ${characteristic.uuid}, deviceId: ${characteristic.deviceID}: ${error}`);
538
537
  if (this.runPromise) {
539
538
  let ERROR = hdShared.HardwareErrorCode.BleCharacteristicNotifyError;
540
539
  if ((_a = error.reason) === null || _a === void 0 ? void 0 : _a.includes('The connection has timed out unexpectedly')) {
@@ -549,11 +548,11 @@ class ReactNativeBleTransport {
549
548
  ((_f = error.reason) === null || _f === void 0 ? void 0 : _f.includes('Writing is not permitted')) ||
550
549
  ((_g = error.reason) === null || _g === void 0 ? void 0 : _g.includes('notify change failed for device'))) {
551
550
  this.runPromise.reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleCharacteristicNotifyChangeFailure));
552
- this.Log.debug(`${hdShared.HardwareErrorCode.BleCharacteristicNotifyChangeFailure} ${error.message} ${error.reason}`);
551
+ Log === null || Log === void 0 ? void 0 : Log.debug(`${hdShared.HardwareErrorCode.BleCharacteristicNotifyChangeFailure} ${error.message} ${error.reason}`);
553
552
  return;
554
553
  }
555
554
  this.runPromise.reject(hdShared.ERRORS.TypedError(ERROR));
556
- this.Log.debug(': monitor notify error, and has unreleased Promise', Error);
555
+ Log === null || Log === void 0 ? void 0 : Log.debug(': monitor notify error, and has unreleased Promise', Error);
557
556
  }
558
557
  return;
559
558
  }
@@ -577,22 +576,24 @@ class ReactNativeBleTransport {
577
576
  }
578
577
  }
579
578
  catch (error) {
580
- this.Log.debug('monitor data error: ', error);
579
+ Log === null || Log === void 0 ? void 0 : Log.debug('monitor data error: ', error);
581
580
  (_j = this.runPromise) === null || _j === void 0 ? void 0 : _j.reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleWriteCharacteristicError));
582
581
  }
583
582
  }, uuid);
584
- return () => {
585
- this.Log.debug('remove characteristic monitor: ', characteristic.uuid);
586
- subscription.remove();
587
- };
583
+ return subscription;
588
584
  }
589
585
  release(uuid) {
590
- var _a;
586
+ var _a, _b, _c;
591
587
  return __awaiter(this, void 0, void 0, function* () {
592
588
  const transport = transportCache[uuid];
593
589
  if (transport) {
590
+ Log === null || Log === void 0 ? void 0 : Log.debug('release: removing disconnect subscription for device: ', uuid);
591
+ (_a = transport.disconnectSubscription) === null || _a === void 0 ? void 0 : _a.remove();
592
+ transport.disconnectSubscription = undefined;
593
+ 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);
594
+ (_c = transport.notifySubscription) === null || _c === void 0 ? void 0 : _c.remove();
595
+ transport.notifySubscription = undefined;
594
596
  delete transportCache[uuid];
595
- (_a = transport.nofitySubscription) === null || _a === void 0 ? void 0 : _a.call(transport);
596
597
  if (reactNative.Platform.OS === 'android') ;
597
598
  }
598
599
  return Promise.resolve(true);
@@ -612,7 +613,7 @@ class ReactNativeBleTransport {
612
613
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.TransportNotConfigured);
613
614
  }
614
615
  const forceRun = name === 'Initialize' || name === 'Cancel';
615
- this.Log.debug('transport-react-native call this.runPromise', this.runPromise);
616
+ Log === null || Log === void 0 ? void 0 : Log.debug('transport-react-native call this.runPromise', this.runPromise);
616
617
  if (this.runPromise && !forceRun) {
617
618
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.TransportCallInProgress);
618
619
  }
@@ -623,16 +624,16 @@ class ReactNativeBleTransport {
623
624
  this.runPromise = hdShared.createDeferred();
624
625
  const messages = this._messages;
625
626
  if (name === 'ResourceUpdate' || name === 'ResourceAck') {
626
- this.Log.debug('transport-react-native', 'call-', ' name: ', name, ' data: ', {
627
+ Log === null || Log === void 0 ? void 0 : Log.debug('transport-react-native', 'call-', ' name: ', name, ' data: ', {
627
628
  file_name: data === null || data === void 0 ? void 0 : data.file_name,
628
629
  hash: data === null || data === void 0 ? void 0 : data.hash,
629
630
  });
630
631
  }
631
632
  else if (transport.LogBlockCommand.has(name)) {
632
- this.Log.debug('transport-react-native', 'call-', ' name: ', name);
633
+ Log === null || Log === void 0 ? void 0 : Log.debug('transport-react-native', 'call-', ' name: ', name);
633
634
  }
634
635
  else {
635
- this.Log.debug('transport-react-native', 'call-', ' name: ', name, ' data: ', data);
636
+ Log === null || Log === void 0 ? void 0 : Log.debug('transport-react-native', 'call-', ' name: ', name, ' data: ', data);
636
637
  }
637
638
  const buffers = buildBuffers(messages, name, data);
638
639
  function writeChunkedData(buffers, writeFunction, onError) {
@@ -661,7 +662,7 @@ class ReactNativeBleTransport {
661
662
  if (name === 'EmmcFileWrite') {
662
663
  yield writeChunkedData(buffers, data => transport$1.writeWithRetry(data), e => {
663
664
  this.runPromise = null;
664
- this.Log.error('writeCharacteristic write error: ', e);
665
+ Log === null || Log === void 0 ? void 0 : Log.error('writeCharacteristic write error: ', e);
665
666
  });
666
667
  }
667
668
  else if (name === 'FirmwareUpload') {
@@ -669,7 +670,7 @@ class ReactNativeBleTransport {
669
670
  yield transport$1.writeCharacteristic.writeWithoutResponse(data);
670
671
  }), e => {
671
672
  this.runPromise = null;
672
- this.Log.error('writeCharacteristic write error: ', e);
673
+ Log === null || Log === void 0 ? void 0 : Log.error('writeCharacteristic write error: ', e);
673
674
  });
674
675
  }
675
676
  else {
@@ -679,7 +680,7 @@ class ReactNativeBleTransport {
679
680
  yield transport$1.writeCharacteristic.writeWithoutResponse(outData);
680
681
  }
681
682
  catch (e) {
682
- this.Log.debug('writeCharacteristic write error: ', e);
683
+ Log === null || Log === void 0 ? void 0 : Log.debug('writeCharacteristic write error: ', e);
683
684
  this.runPromise = null;
684
685
  if (e.errorCode === reactNativeBlePlx.BleErrorCode.DeviceDisconnected) {
685
686
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceNotBonded);
@@ -698,12 +699,12 @@ class ReactNativeBleTransport {
698
699
  if (typeof response !== 'string') {
699
700
  throw new Error('Returning data is not string.');
700
701
  }
701
- this.Log.debug('receive data: ', response);
702
+ Log === null || Log === void 0 ? void 0 : Log.debug('receive data: ', response);
702
703
  const jsonData = receiveOne(messages, response);
703
704
  return check.call(jsonData);
704
705
  }
705
706
  catch (e) {
706
- this.Log.error('call error: ', e);
707
+ Log === null || Log === void 0 ? void 0 : Log.error('call error: ', e);
707
708
  throw e;
708
709
  }
709
710
  finally {
@@ -715,25 +716,36 @@ class ReactNativeBleTransport {
715
716
  this.stopped = true;
716
717
  }
717
718
  disconnect(session) {
718
- var _a, _b, _c, _d;
719
+ var _a, _b, _c, _d, _e;
719
720
  return __awaiter(this, void 0, void 0, function* () {
720
- this.Log.debug('transport-react-native transport resetSession: ', session);
721
+ Log === null || Log === void 0 ? void 0 : Log.debug('transport-react-native transport resetSession: ', session);
721
722
  const transport = transportCache[session];
722
- if (transport === null || transport === void 0 ? void 0 : transport.nofitySubscription) {
723
+ if (transport === null || transport === void 0 ? void 0 : transport.disconnectSubscription) {
724
+ try {
725
+ Log === null || Log === void 0 ? void 0 : Log.debug('disconnect: removing disconnect subscription');
726
+ transport.disconnectSubscription.remove();
727
+ transport.disconnectSubscription = undefined;
728
+ }
729
+ catch (e) {
730
+ Log === null || Log === void 0 ? void 0 : Log.debug('disconnect: remove disconnect subscription error (ignored): ', e);
731
+ }
732
+ }
733
+ if (transport === null || transport === void 0 ? void 0 : transport.notifySubscription) {
723
734
  try {
724
- transport.nofitySubscription();
725
- transport.nofitySubscription = undefined;
735
+ Log === null || Log === void 0 ? void 0 : Log.debug('disconnect: removing notify subscription, characteristic: ', (_a = transport.notifyCharacteristic) === null || _a === void 0 ? void 0 : _a.uuid);
736
+ transport.notifySubscription.remove();
737
+ transport.notifySubscription = undefined;
726
738
  }
727
739
  catch (e) {
728
- this.Log.error('resetSession: remove notify subscription error: ', e);
740
+ Log === null || Log === void 0 ? void 0 : Log.error('disconnect: remove notify subscription error: ', e);
729
741
  }
730
742
  }
731
743
  if (session) {
732
744
  try {
733
- yield ((_a = this.blePlxManager) === null || _a === void 0 ? void 0 : _a.cancelTransaction(session));
745
+ yield ((_b = this.blePlxManager) === null || _b === void 0 ? void 0 : _b.cancelTransaction(session));
734
746
  }
735
747
  catch (e) {
736
- this.Log.debug('resetSession: cancel transaction error (ignored): ', (e === null || e === void 0 ? void 0 : e.message) || e);
748
+ Log === null || Log === void 0 ? void 0 : Log.debug('resetSession: cancel transaction error (ignored): ', (e === null || e === void 0 ? void 0 : e.message) || e);
737
749
  }
738
750
  }
739
751
  if (transport === null || transport === void 0 ? void 0 : transport.device) {
@@ -741,33 +753,33 @@ class ReactNativeBleTransport {
741
753
  yield transport.device.cancelConnection();
742
754
  }
743
755
  catch (e) {
744
- this.Log.debug('resetSession: device.cancelConnection error (ignored): ', (e === null || e === void 0 ? void 0 : e.message) || e);
756
+ Log === null || Log === void 0 ? void 0 : Log.debug('resetSession: device.cancelConnection error (ignored): ', (e === null || e === void 0 ? void 0 : e.message) || e);
745
757
  }
746
758
  }
747
759
  try {
748
- yield ((_b = this.blePlxManager) === null || _b === void 0 ? void 0 : _b.cancelDeviceConnection(session));
760
+ yield ((_c = this.blePlxManager) === null || _c === void 0 ? void 0 : _c.cancelDeviceConnection(session));
749
761
  }
750
762
  catch (e) {
751
- this.Log.debug('resetSession: manager.cancelDeviceConnection error (ignored): ', (e === null || e === void 0 ? void 0 : e.message) || e);
763
+ Log === null || Log === void 0 ? void 0 : Log.debug('resetSession: manager.cancelDeviceConnection error (ignored): ', (e === null || e === void 0 ? void 0 : e.message) || e);
752
764
  }
753
765
  if (transportCache[session]) {
754
766
  delete transportCache[session];
755
767
  }
756
768
  try {
757
- (_c = this.emitter) === null || _c === void 0 ? void 0 : _c.emit('device-disconnect', {
758
- name: (_d = transport === null || transport === void 0 ? void 0 : transport.device) === null || _d === void 0 ? void 0 : _d.name,
769
+ (_d = this.emitter) === null || _d === void 0 ? void 0 : _d.emit('device-disconnect', {
770
+ name: (_e = transport === null || transport === void 0 ? void 0 : transport.device) === null || _e === void 0 ? void 0 : _e.name,
759
771
  id: session,
760
772
  connectId: session,
761
773
  });
762
774
  }
763
775
  catch (e) {
764
- this.Log.error('resetSession: emit disconnect event error: ', e);
776
+ Log === null || Log === void 0 ? void 0 : Log.error('resetSession: emit disconnect event error: ', e);
765
777
  }
766
778
  yield new Promise(resolve => setTimeout(() => resolve(), 100));
767
779
  });
768
780
  }
769
781
  cancel() {
770
- this.Log.debug('transport-react-native transport cancel');
782
+ Log === null || Log === void 0 ? void 0 : Log.debug('transport-react-native transport cancel');
771
783
  if (this.runPromise) ;
772
784
  this.runPromise = null;
773
785
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/hd-transport-react-native",
3
- "version": "1.1.22",
3
+ "version": "1.1.23",
4
4
  "homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -19,10 +19,11 @@
19
19
  "lint:fix": "eslint . --fix"
20
20
  },
21
21
  "dependencies": {
22
- "@onekeyfe/hd-shared": "1.1.22",
23
- "@onekeyfe/hd-transport": "1.1.22",
22
+ "@onekeyfe/hd-core": "1.1.23",
23
+ "@onekeyfe/hd-shared": "1.1.23",
24
+ "@onekeyfe/hd-transport": "1.1.23",
24
25
  "@onekeyfe/react-native-ble-utils": "^0.1.4",
25
26
  "react-native-ble-plx": "3.5.0"
26
27
  },
27
- "gitHead": "d9d816ec5c818397549202ecb42d127af99a03f1"
28
+ "gitHead": "eb24e6d66c84185b820a82b880c9707f3f548131"
28
29
  }
@@ -1,7 +1,7 @@
1
1
  import { BleErrorCode } from 'react-native-ble-plx';
2
2
  import { LoggerNames, getLogger, wait } from '@onekeyfe/hd-core';
3
3
 
4
- import type { Characteristic, Device } from 'react-native-ble-plx';
4
+ import type { Characteristic, Device, Subscription } from 'react-native-ble-plx';
5
5
  // import { wait } from '@onekeyfe/hd-core/src/utils';
6
6
 
7
7
  const Log = getLogger(LoggerNames.HdBleTransport);
@@ -19,7 +19,9 @@ export default class BleTransport {
19
19
 
20
20
  notifyCharacteristic: Characteristic;
21
21
 
22
- nofitySubscription?: () => void;
22
+ notifySubscription?: Subscription;
23
+
24
+ disconnectSubscription?: Subscription;
23
25
 
24
26
  static MAX_RETRIES = 5;
25
27
 
package/src/index.ts CHANGED
@@ -14,6 +14,7 @@ import transport, {
14
14
  type OneKeyDeviceInfoBase,
15
15
  } from '@onekeyfe/hd-transport';
16
16
  import { ERRORS, HardwareErrorCode, createDeferred, isOnekeyDevice } from '@onekeyfe/hd-shared';
17
+ import { LoggerNames, getLogger } from '@onekeyfe/hd-core';
17
18
 
18
19
  import { getConnectedDeviceIds, onDeviceBondState, pairDevice } from './BleManager';
19
20
  import { subscribeBleOn } from './subscribeBleOn';
@@ -28,13 +29,15 @@ import BleTransport from './BleTransport';
28
29
  import timer from './utils/timer';
29
30
 
30
31
  import type { Deferred } from '@onekeyfe/hd-shared';
31
- import type { Characteristic, Device } from 'react-native-ble-plx';
32
+ import type { Characteristic, Device, Subscription } from 'react-native-ble-plx';
32
33
  import type EventEmitter from 'events';
33
34
  import type { BleAcquireInput, TransportOptions } from './types';
34
35
 
35
36
  const { check, buildBuffers, receiveOne, parseConfigure } = transport;
36
37
 
37
- const transportCache: Record<string, any> = {};
38
+ const Log = getLogger(LoggerNames.HdBleTransport);
39
+
40
+ const transportCache: Record<string, BleTransport> = {};
38
41
 
39
42
  let connectOptions: Record<string, unknown> = {
40
43
  requestMTU: 256,
@@ -99,16 +102,13 @@ export default class ReactNativeBleTransport {
99
102
 
100
103
  runPromise: Deferred<any> | null = null;
101
104
 
102
- Log?: any;
103
-
104
105
  emitter?: EventEmitter;
105
106
 
106
107
  constructor(options: TransportOptions) {
107
108
  this.scanTimeout = options.scanTimeout ?? 3000;
108
109
  }
109
110
 
110
- init(logger: any, emitter: EventEmitter) {
111
- this.Log = logger;
111
+ init(_logger: any, emitter: EventEmitter) {
112
112
  this.emitter = emitter;
113
113
  }
114
114
 
@@ -141,20 +141,20 @@ export default class ReactNativeBleTransport {
141
141
  try {
142
142
  await subscribeBleOn(blePlxManager);
143
143
  } catch (error) {
144
- this.Log.debug('subscribeBleOn error: ', error);
144
+ Log?.debug('subscribeBleOn error: ', error);
145
145
  reject(error);
146
146
  return;
147
147
  }
148
148
 
149
149
  if (Platform.OS === 'android' && Platform.Version >= 31) {
150
- this.Log.debug('requesting permissions, please wait...');
150
+ Log?.debug('requesting permissions, please wait...');
151
151
 
152
152
  const resultConnect = await PermissionsAndroid.requestMultiple([
153
153
  PermissionsAndroid.PERMISSIONS.BLUETOOTH_CONNECT,
154
154
  PermissionsAndroid.PERMISSIONS.BLUETOOTH_SCAN,
155
155
  ]);
156
156
 
157
- this.Log.debug('requesting permissions, result: ', resultConnect);
157
+ Log?.debug('requesting permissions, result: ', resultConnect);
158
158
  if (
159
159
  resultConnect[PermissionsAndroid.PERMISSIONS.BLUETOOTH_CONNECT] !== 'granted' ||
160
160
  resultConnect[PermissionsAndroid.PERMISSIONS.BLUETOOTH_SCAN] !== 'granted'
@@ -171,8 +171,8 @@ export default class ReactNativeBleTransport {
171
171
  },
172
172
  (error, device) => {
173
173
  if (error) {
174
- this.Log.debug('ble scan manager: ', blePlxManager);
175
- this.Log.debug('ble scan error: ', error);
174
+ Log?.debug('ble scan manager: ', blePlxManager);
175
+ Log?.debug('ble scan error: ', error);
176
176
  if (
177
177
  [BleErrorCode.BluetoothPoweredOff, BleErrorCode.BluetoothInUnknownState].includes(
178
178
  error.errorCode
@@ -195,20 +195,20 @@ export default class ReactNativeBleTransport {
195
195
  }
196
196
 
197
197
  if (isOnekeyDevice(device?.name ?? null, device?.id)) {
198
- this.Log.debug('search device start ======================');
198
+ Log?.debug('search device start ======================');
199
199
  const { name, localName, id } = device ?? {};
200
- this.Log.debug(
200
+ Log?.debug(
201
201
  `device name: ${name ?? ''}\nlocalName: ${localName ?? ''}\nid: ${id ?? ''}`
202
202
  );
203
203
  addDevice(device as unknown as Device);
204
- this.Log.debug('search device end ======================\n');
204
+ Log?.debug('search device end ======================\n');
205
205
  }
206
206
  }
207
207
  );
208
208
 
209
209
  getConnectedDeviceIds(getBluetoothServiceUuids()).then(devices => {
210
210
  for (const device of devices) {
211
- this.Log.debug('search connected peripheral: ', device.id);
211
+ Log?.debug('search connected peripheral: ', device.id);
212
212
  addDevice(device as unknown as Device);
213
213
  }
214
214
  });
@@ -240,23 +240,20 @@ export default class ReactNativeBleTransport {
240
240
  * If the transport is not released due to an exception operation
241
241
  * it will be handled again here
242
242
  */
243
- this.Log.debug('transport not be released, will release: ', uuid);
243
+ Log?.debug('transport not be released, will release: ', uuid);
244
244
  await this.release(uuid);
245
245
  }
246
246
 
247
247
  if (forceCleanRunPromise && this.runPromise) {
248
248
  this.runPromise.reject(ERRORS.TypedError(HardwareErrorCode.BleForceCleanRunPromise));
249
- this.Log.debug(
250
- 'Force clean Bluetooth run promise, forceCleanRunPromise: ',
251
- forceCleanRunPromise
252
- );
249
+ Log?.debug('Force clean Bluetooth run promise, forceCleanRunPromise: ', forceCleanRunPromise);
253
250
  }
254
251
 
255
252
  const blePlxManager = await this.getPlxManager();
256
253
  try {
257
254
  await subscribeBleOn(blePlxManager);
258
255
  } catch (error) {
259
- this.Log.debug('subscribeBleOn error: ', error);
256
+ Log?.debug('subscribeBleOn error: ', error);
260
257
  throw error;
261
258
  }
262
259
 
@@ -276,25 +273,25 @@ export default class ReactNativeBleTransport {
276
273
  if (!device) {
277
274
  const connectedDevice = await blePlxManager.connectedDevices(getBluetoothServiceUuids());
278
275
  const deviceFilter = connectedDevice.filter(device => device.id === uuid);
279
- this.Log.debug(`found connected device count: ${deviceFilter.length}`);
276
+ Log?.debug(`found connected device count: ${deviceFilter.length}`);
280
277
  [device] = deviceFilter;
281
278
  }
282
279
 
283
280
  if (!device) {
284
- this.Log.debug('try to connect to device: ', uuid);
281
+ Log?.debug('try to connect to device: ', uuid);
285
282
  try {
286
283
  device = await blePlxManager.connectToDevice(uuid, connectOptions);
287
284
  } catch (e) {
288
- this.Log.debug('try to connect to device has error: ', e);
285
+ Log?.debug('try to connect to device has error: ', e);
289
286
  if (
290
287
  e.errorCode === BleErrorCode.DeviceMTUChangeFailed ||
291
288
  e.errorCode === BleErrorCode.OperationCancelled
292
289
  ) {
293
290
  connectOptions = {};
294
- this.Log.debug('first try to reconnect without params');
291
+ Log?.debug('first try to reconnect without params');
295
292
  device = await blePlxManager.connectToDevice(uuid);
296
293
  } else if (e.errorCode === BleErrorCode.DeviceAlreadyConnected) {
297
- this.Log.debug('device already connected');
294
+ Log?.debug('device already connected');
298
295
  throw ERRORS.TypedError(HardwareErrorCode.BleAlreadyConnected);
299
296
  } else {
300
297
  remapError(e);
@@ -307,26 +304,26 @@ export default class ReactNativeBleTransport {
307
304
  }
308
305
 
309
306
  if (!(await device.isConnected())) {
310
- this.Log.debug('not connected, try to connect to device: ', uuid);
307
+ Log?.debug('not connected, try to connect to device: ', uuid);
311
308
 
312
309
  try {
313
310
  await device.connect(connectOptions);
314
311
  } catch (e) {
315
- this.Log.debug('not connected, try to connect to device has error: ', e);
312
+ Log?.debug('not connected, try to connect to device has error: ', e);
316
313
  if (
317
314
  e.errorCode === BleErrorCode.DeviceMTUChangeFailed ||
318
315
  e.errorCode === BleErrorCode.OperationCancelled
319
316
  ) {
320
317
  connectOptions = {};
321
- this.Log.debug('second try to reconnect without params');
318
+ Log?.debug('second try to reconnect without params');
322
319
  try {
323
320
  await device.connect();
324
321
  } catch (e) {
325
- this.Log.debug('last try to reconnect error: ', e);
322
+ Log?.debug('last try to reconnect error: ', e);
326
323
  // last try to reconnect device if this issue exists
327
324
  // https://github.com/dotintent/react-native-ble-plx/issues/426
328
325
  if (e.errorCode === BleErrorCode.OperationCancelled) {
329
- this.Log.debug('last try to reconnect');
326
+ Log?.debug('last try to reconnect');
330
327
  await device.cancelConnection();
331
328
  await device.connect();
332
329
  }
@@ -348,17 +345,17 @@ export default class ReactNativeBleTransport {
348
345
  infos = getInfosForServiceUuid(serviceUuid, 'classic');
349
346
  break;
350
347
  } catch (e) {
351
- this.Log.error(e);
348
+ Log?.error(e);
352
349
  }
353
350
  }
354
351
  }
355
352
 
356
353
  if (!infos) {
357
354
  try {
358
- this.Log.debug('cancel connection when service not found');
355
+ Log?.debug('cancel connection when service not found');
359
356
  await device.cancelConnection();
360
357
  } catch (e) {
361
- this.Log.debug('cancel connection error when service not found: ', e.message || e.reason);
358
+ Log?.debug('cancel connection error when service not found: ', e.message || e.reason);
362
359
  }
363
360
  throw ERRORS.TypedError(HardwareErrorCode.BleServiceNotFound);
364
361
  }
@@ -405,7 +402,7 @@ export default class ReactNativeBleTransport {
405
402
  await this.release(uuid);
406
403
 
407
404
  const transport = new BleTransport(device, writeCharacteristic, notifyCharacteristic);
408
- transport.nofitySubscription = this._monitorCharacteristic(
405
+ transport.notifySubscription = this._monitorCharacteristic(
409
406
  transport.notifyCharacteristic,
410
407
  uuid
411
408
  );
@@ -417,9 +414,9 @@ export default class ReactNativeBleTransport {
417
414
  connectId: device.id,
418
415
  });
419
416
 
420
- const disconnectSubscription = device.onDisconnected(() => {
417
+ transport.disconnectSubscription = device.onDisconnected(() => {
421
418
  try {
422
- this.Log.debug('device disconnect: ', device?.id);
419
+ Log?.debug('device disconnect: ', device?.id);
423
420
  this.emitter?.emit('device-disconnect', {
424
421
  name: device?.name,
425
422
  id: device?.id,
@@ -429,22 +426,21 @@ export default class ReactNativeBleTransport {
429
426
  this.runPromise.reject(ERRORS.TypedError(HardwareErrorCode.BleConnectedError));
430
427
  }
431
428
  } catch (e) {
432
- this.Log.debug('device disconnect error: ', e);
429
+ Log?.debug('device disconnect error: ', e);
433
430
  } finally {
434
431
  this.release(uuid);
435
- disconnectSubscription?.remove();
436
432
  }
437
433
  });
438
434
 
439
435
  return { uuid };
440
436
  }
441
437
 
442
- _monitorCharacteristic(characteristic: Characteristic, uuid: string) {
438
+ _monitorCharacteristic(characteristic: Characteristic, uuid: string): Subscription {
443
439
  let bufferLength = 0;
444
440
  let buffer: any[] = [];
445
441
  const subscription = characteristic.monitor((error, c) => {
446
442
  if (error) {
447
- this.Log.debug(
443
+ Log?.debug(
448
444
  `error monitor ${characteristic.uuid}, deviceId: ${characteristic.deviceID}: ${
449
445
  error as unknown as string
450
446
  }`
@@ -471,13 +467,13 @@ export default class ReactNativeBleTransport {
471
467
  this.runPromise.reject(
472
468
  ERRORS.TypedError(HardwareErrorCode.BleCharacteristicNotifyChangeFailure)
473
469
  );
474
- this.Log.debug(
470
+ Log?.debug(
475
471
  `${HardwareErrorCode.BleCharacteristicNotifyChangeFailure} ${error.message} ${error.reason}`
476
472
  );
477
473
  return;
478
474
  }
479
475
  this.runPromise.reject(ERRORS.TypedError(ERROR));
480
- this.Log.debug(': monitor notify error, and has unreleased Promise', Error);
476
+ Log?.debug(': monitor notify error, and has unreleased Promise', Error);
481
477
  }
482
478
 
483
479
  return;
@@ -510,23 +506,33 @@ export default class ReactNativeBleTransport {
510
506
  this.runPromise?.resolve(value.toString('hex'));
511
507
  }
512
508
  } catch (error) {
513
- this.Log.debug('monitor data error: ', error);
509
+ Log?.debug('monitor data error: ', error);
514
510
  this.runPromise?.reject(ERRORS.TypedError(HardwareErrorCode.BleWriteCharacteristicError));
515
511
  }
516
512
  }, uuid);
517
513
 
518
- return () => {
519
- this.Log.debug('remove characteristic monitor: ', characteristic.uuid);
520
- subscription.remove();
521
- };
514
+ return subscription;
522
515
  }
523
516
 
524
517
  async release(uuid: string) {
525
518
  const transport = transportCache[uuid];
526
519
 
527
520
  if (transport) {
521
+ // Clean up disconnect subscription first to prevent callbacks on released transport
522
+ Log?.debug('release: removing disconnect subscription for device: ', uuid);
523
+ transport.disconnectSubscription?.remove();
524
+ transport.disconnectSubscription = undefined;
525
+
526
+ // Clean up notify subscription
527
+ Log?.debug(
528
+ 'release: removing notify subscription, characteristic: ',
529
+ transport.notifyCharacteristic?.uuid
530
+ );
531
+ transport.notifySubscription?.remove();
532
+ transport.notifySubscription = undefined;
533
+
528
534
  delete transportCache[uuid];
529
- transport.nofitySubscription?.();
535
+
530
536
  // Temporary close the Android disconnect after each request
531
537
  if (Platform.OS === 'android') {
532
538
  // await this.blePlxManager?.cancelDeviceConnection(uuid);
@@ -551,12 +557,12 @@ export default class ReactNativeBleTransport {
551
557
 
552
558
  const forceRun = name === 'Initialize' || name === 'Cancel';
553
559
 
554
- this.Log.debug('transport-react-native call this.runPromise', this.runPromise);
560
+ Log?.debug('transport-react-native call this.runPromise', this.runPromise);
555
561
  if (this.runPromise && !forceRun) {
556
562
  throw ERRORS.TypedError(HardwareErrorCode.TransportCallInProgress);
557
563
  }
558
564
 
559
- const transport = transportCache[uuid] as BleTransport;
565
+ const transport = transportCache[uuid];
560
566
  if (!transport) {
561
567
  throw ERRORS.TypedError(HardwareErrorCode.TransportNotFound);
562
568
  }
@@ -565,14 +571,14 @@ export default class ReactNativeBleTransport {
565
571
  const messages = this._messages;
566
572
  // Upload resources on low-end phones may OOM
567
573
  if (name === 'ResourceUpdate' || name === 'ResourceAck') {
568
- this.Log.debug('transport-react-native', 'call-', ' name: ', name, ' data: ', {
574
+ Log?.debug('transport-react-native', 'call-', ' name: ', name, ' data: ', {
569
575
  file_name: data?.file_name,
570
576
  hash: data?.hash,
571
577
  });
572
578
  } else if (LogBlockCommand.has(name)) {
573
- this.Log.debug('transport-react-native', 'call-', ' name: ', name);
579
+ Log?.debug('transport-react-native', 'call-', ' name: ', name);
574
580
  } else {
575
- this.Log.debug('transport-react-native', 'call-', ' name: ', name, ' data: ', data);
581
+ Log?.debug('transport-react-native', 'call-', ' name: ', name, ' data: ', data);
576
582
  }
577
583
 
578
584
  const buffers = buildBuffers(messages, name, data);
@@ -610,7 +616,7 @@ export default class ReactNativeBleTransport {
610
616
  data => transport.writeWithRetry(data),
611
617
  e => {
612
618
  this.runPromise = null;
613
- this.Log.error('writeCharacteristic write error: ', e);
619
+ Log?.error('writeCharacteristic write error: ', e);
614
620
  }
615
621
  );
616
622
  } else if (name === 'FirmwareUpload') {
@@ -621,7 +627,7 @@ export default class ReactNativeBleTransport {
621
627
  },
622
628
  e => {
623
629
  this.runPromise = null;
624
- this.Log.error('writeCharacteristic write error: ', e);
630
+ Log?.error('writeCharacteristic write error: ', e);
625
631
  }
626
632
  );
627
633
  } else {
@@ -632,7 +638,7 @@ export default class ReactNativeBleTransport {
632
638
  try {
633
639
  await transport.writeCharacteristic.writeWithoutResponse(outData);
634
640
  } catch (e) {
635
- this.Log.debug('writeCharacteristic write error: ', e);
641
+ Log?.debug('writeCharacteristic write error: ', e);
636
642
  this.runPromise = null;
637
643
  if (e.errorCode === BleErrorCode.DeviceDisconnected) {
638
644
  throw ERRORS.TypedError(HardwareErrorCode.BleDeviceNotBonded);
@@ -652,11 +658,11 @@ export default class ReactNativeBleTransport {
652
658
  throw new Error('Returning data is not string.');
653
659
  }
654
660
 
655
- this.Log.debug('receive data: ', response);
661
+ Log?.debug('receive data: ', response);
656
662
  const jsonData = receiveOne(messages, response);
657
663
  return check.call(jsonData);
658
664
  } catch (e) {
659
- this.Log.error('call error: ', e);
665
+ Log?.error('call error: ', e);
660
666
  throw e;
661
667
  } finally {
662
668
  this.runPromise = null;
@@ -668,16 +674,32 @@ export default class ReactNativeBleTransport {
668
674
  }
669
675
 
670
676
  async disconnect(session: string) {
671
- this.Log.debug('transport-react-native transport resetSession: ', session);
672
- const transport = transportCache[session] as BleTransport;
677
+ Log?.debug('transport-react-native transport resetSession: ', session);
678
+ const transport = transportCache[session];
679
+
680
+ // Clean up disconnect subscription first to prevent onDisconnected callback
681
+ // from being triggered when we cancel the connection below
682
+ if (transport?.disconnectSubscription) {
683
+ try {
684
+ Log?.debug('disconnect: removing disconnect subscription');
685
+ transport.disconnectSubscription.remove();
686
+ transport.disconnectSubscription = undefined;
687
+ } catch (e) {
688
+ Log?.debug('disconnect: remove disconnect subscription error (ignored): ', e);
689
+ }
690
+ }
673
691
 
674
692
  // cancel the notify subscription
675
- if (transport?.nofitySubscription) {
693
+ if (transport?.notifySubscription) {
676
694
  try {
677
- transport.nofitySubscription();
678
- transport.nofitySubscription = undefined;
695
+ Log?.debug(
696
+ 'disconnect: removing notify subscription, characteristic: ',
697
+ transport.notifyCharacteristic?.uuid
698
+ );
699
+ transport.notifySubscription.remove();
700
+ transport.notifySubscription = undefined;
679
701
  } catch (e) {
680
- this.Log.error('resetSession: remove notify subscription error: ', e);
702
+ Log?.error('disconnect: remove notify subscription error: ', e);
681
703
  }
682
704
  }
683
705
 
@@ -686,7 +708,7 @@ export default class ReactNativeBleTransport {
686
708
  try {
687
709
  await this.blePlxManager?.cancelTransaction(session);
688
710
  } catch (e) {
689
- this.Log.debug('resetSession: cancel transaction error (ignored): ', e?.message || e);
711
+ Log?.debug('resetSession: cancel transaction error (ignored): ', e?.message || e);
690
712
  }
691
713
  }
692
714
 
@@ -695,7 +717,7 @@ export default class ReactNativeBleTransport {
695
717
  try {
696
718
  await transport.device.cancelConnection();
697
719
  } catch (e) {
698
- this.Log.debug('resetSession: device.cancelConnection error (ignored): ', e?.message || e);
720
+ Log?.debug('resetSession: device.cancelConnection error (ignored): ', e?.message || e);
699
721
  }
700
722
  }
701
723
 
@@ -703,10 +725,7 @@ export default class ReactNativeBleTransport {
703
725
  try {
704
726
  await this.blePlxManager?.cancelDeviceConnection(session);
705
727
  } catch (e) {
706
- this.Log.debug(
707
- 'resetSession: manager.cancelDeviceConnection error (ignored): ',
708
- e?.message || e
709
- );
728
+ Log?.debug('resetSession: manager.cancelDeviceConnection error (ignored): ', e?.message || e);
710
729
  }
711
730
 
712
731
  // clear the transport cache
@@ -722,14 +741,14 @@ export default class ReactNativeBleTransport {
722
741
  connectId: session,
723
742
  });
724
743
  } catch (e) {
725
- this.Log.error('resetSession: emit disconnect event error: ', e);
744
+ Log?.error('resetSession: emit disconnect event error: ', e);
726
745
  }
727
746
  // eslint-disable-next-line no-promise-executor-return
728
747
  await new Promise<void>(resolve => setTimeout(() => resolve(), 100));
729
748
  }
730
749
 
731
750
  cancel() {
732
- this.Log.debug('transport-react-native transport cancel');
751
+ Log?.debug('transport-react-native transport cancel');
733
752
  if (this.runPromise) {
734
753
  // this.runPromise.reject(new Error('Transport_CallCanceled'));
735
754
  }