@onekeyfe/hd-transport-electron 1.2.0-alpha.68 → 1.2.0-alpha.69

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.
@@ -0,0 +1,2 @@
1
+ export declare function resolveBlePacketCapacity(mtu: number | null | undefined, maximumPacketCapacity: number, fallbackPacketCapacity: number): number;
2
+ //# sourceMappingURL=ble-packet-capacity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ble-packet-capacity.d.ts","sourceRoot":"","sources":["../src/ble-packet-capacity.ts"],"names":[],"mappings":"AAEA,wBAAgB,wBAAwB,CACtC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAC9B,qBAAqB,EAAE,MAAM,EAC7B,sBAAsB,EAAE,MAAM,GAC7B,MAAM,CAMR"}
@@ -32,7 +32,7 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
32
32
 
33
33
  function initNobleBleSupport(webContents) {
34
34
  return __awaiter(this, void 0, void 0, function* () {
35
- const { setupNobleBleHandlers } = yield Promise.resolve().then(function () { return require('./noble-ble-handler-a0b2f06d.js'); });
35
+ const { setupNobleBleHandlers } = yield Promise.resolve().then(function () { return require('./noble-ble-handler-7ac9c43d.js'); });
36
36
  setupNobleBleHandlers(webContents);
37
37
  });
38
38
  }
package/dist/index.d.ts CHANGED
@@ -6,6 +6,7 @@ interface DeviceInfo extends OneKeyDeviceInfoBase {
6
6
  id: string;
7
7
  name: string;
8
8
  state: string;
9
+ mtu?: number;
9
10
  }
10
11
  interface CharacteristicPair {
11
12
  write: Characteristic;
@@ -38,6 +39,7 @@ interface NobleBleAPI {
38
39
  getDevice: (uuid: string) => Promise<{
39
40
  id: string;
40
41
  name: string;
42
+ mtu?: number;
41
43
  } | null>;
42
44
  connect: (uuid: string) => Promise<void>;
43
45
  disconnect: (uuid: string) => Promise<void>;
@@ -45,6 +47,10 @@ interface NobleBleAPI {
45
47
  unsubscribe: (uuid: string) => Promise<void>;
46
48
  write: (uuid: string, data: string) => Promise<void>;
47
49
  onNotification: (callback: (deviceId: string, data: string) => void) => () => void;
50
+ onMtuChanged?: (callback: (device: {
51
+ id: string;
52
+ mtu: number;
53
+ }) => void) => () => void;
48
54
  onDeviceDisconnected: (callback: (device: {
49
55
  id: string;
50
56
  name: string;
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var index = require('./index-84fea839.js');
5
+ var index = require('./index-bd1cfdb6.js');
6
6
 
7
7
 
8
8
 
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-84fea839.js');
3
+ var index = require('./index-bd1cfdb6.js');
4
4
  var hdShared = require('@onekeyfe/hd-shared');
5
5
  var pRetry = require('p-retry');
6
6
 
@@ -8,6 +8,14 @@ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'defau
8
8
 
9
9
  var pRetry__default = /*#__PURE__*/_interopDefaultLegacy(pRetry);
10
10
 
11
+ const BLE_ATT_HEADER_BYTES = 3;
12
+ function resolveBlePacketCapacity(mtu, maximumPacketCapacity, fallbackPacketCapacity) {
13
+ if (typeof mtu !== 'number' || !Number.isFinite(mtu) || mtu <= BLE_ATT_HEADER_BYTES) {
14
+ return fallbackPacketCapacity;
15
+ }
16
+ return Math.min(maximumPacketCapacity, Math.floor(mtu) - BLE_ATT_HEADER_BYTES);
17
+ }
18
+
11
19
  function safeLog(logger, level, message, ...args) {
12
20
  if (logger) {
13
21
  logger[level](message, ...args);
@@ -98,6 +106,7 @@ const notificationCallbacks = new Map();
98
106
  const subscribedDevices = new Map();
99
107
  const subscriptionOperations = new Map();
100
108
  const deviceDisconnectListeners = new Map();
109
+ const deviceMtuListeners = new Map();
101
110
  const ONEKEY_SERVICE_UUIDS = [hdShared.ONEKEY_SERVICE_UUID];
102
111
  const ONEKEY_SERVICE_UUID_ALIASES = hdShared.createKnownBleUuidAliases(hdShared.ONEKEY_SERVICE_UUID);
103
112
  const ONEKEY_WRITE_UUID_ALIASES = hdShared.createKnownBleUuidAliases(hdShared.ONEKEY_WRITE_CHARACTERISTIC_UUID);
@@ -107,8 +116,8 @@ const DEVICE_SCAN_TIMEOUT = 5000;
107
116
  const DEVICE_CHECK_INTERVAL = 500;
108
117
  const SERVICE_DISCOVERY_TIMEOUT = 10000;
109
118
  const BLE_CLEANUP_TIMEOUT = 250;
110
- const BLE_PACKET_SIZE = 192;
111
- const UNIFIED_WRITE_DELAY = 5;
119
+ const BLE_PACKET_SIZE_FALLBACK = 192;
120
+ const BLE_PACKET_SIZE_MAXIMUM = 244;
112
121
  const RETRY_CONFIG = { MAX_ATTEMPTS: 15, WRITE_TIMEOUT: 2000 };
113
122
  const IS_WINDOWS = process.platform === 'win32';
114
123
  const ABORTABLE_WRITE_ERROR_PATTERNS = [
@@ -300,6 +309,11 @@ function cleanupDevice(deviceId, webContents, options = {}) {
300
309
  disconnectEntry.peripheral.removeListener('disconnect', disconnectEntry.listener);
301
310
  deviceDisconnectListeners.delete(deviceId);
302
311
  }
312
+ const mtuEntry = deviceMtuListeners.get(deviceId);
313
+ if (mtuEntry) {
314
+ mtuEntry.peripheral.removeListener('mtu', mtuEntry.listener);
315
+ deviceMtuListeners.delete(deviceId);
316
+ }
303
317
  connectedDevices.delete(deviceId);
304
318
  deviceCharacteristics.delete(deviceId);
305
319
  notificationCallbacks.delete(deviceId);
@@ -343,8 +357,25 @@ function setupDisconnectListener(peripheral, deviceId, webContents) {
343
357
  };
344
358
  deviceDisconnectListeners.set(deviceId, { peripheral, listener });
345
359
  peripheral.on('disconnect', listener);
360
+ setupMtuListener(peripheral, deviceId, webContents);
361
+ }
362
+ function setupMtuListener(peripheral, deviceId, webContents) {
363
+ const existing = deviceMtuListeners.get(deviceId);
364
+ if (existing) {
365
+ existing.peripheral.removeListener('mtu', existing.listener);
366
+ }
367
+ const listener = (mtu) => {
368
+ if (!Number.isFinite(mtu) || mtu <= 0)
369
+ return;
370
+ webContents.send(hdShared.EOneKeyBleMessageKeys.NOBLE_BLE_MTU_CHANGED, {
371
+ id: deviceId,
372
+ mtu,
373
+ });
374
+ };
375
+ deviceMtuListeners.set(deviceId, { peripheral, listener });
376
+ peripheral.on('mtu', listener);
346
377
  }
347
- function writeCharacteristicWithAck(deviceId, writeCharacteristic, buffer) {
378
+ function writeCharacteristicWithoutResponse(deviceId, writeCharacteristic, buffer) {
348
379
  return index.__awaiter(this, void 0, void 0, function* () {
349
380
  return new Promise((resolve, reject) => {
350
381
  writeCharacteristic.write(buffer, true, (error) => {
@@ -376,7 +407,7 @@ function attemptWindowsWriteUntilPaired(deviceId, doGetWriteCharacteristic, payl
376
407
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Write characteristic not available for ${deviceId}`);
377
408
  }
378
409
  try {
379
- yield writeCharacteristicWithAck(deviceId, latestWrite, payload);
410
+ yield writeCharacteristicWithoutResponse(deviceId, latestWrite, payload);
380
411
  }
381
412
  catch (e) {
382
413
  const errorMessage = e instanceof Error ? e.message : String(e);
@@ -444,44 +475,37 @@ function transmitHexDataToDevice(deviceId, hexData) {
444
475
  }
445
476
  const toBuffer = Buffer.from(hexData, 'hex');
446
477
  const doGetWriteCharacteristic = () => { var _a; return (_a = deviceCharacteristics.get(deviceId)) === null || _a === void 0 ? void 0 : _a.write; };
478
+ const packetCapacity = resolveBlePacketCapacity(peripheral.mtu, BLE_PACKET_SIZE_MAXIMUM, BLE_PACKET_SIZE_FALLBACK);
447
479
  if (!IS_WINDOWS || pairedDevices.has(deviceId)) {
448
480
  const writeCharacteristic = doGetWriteCharacteristic();
449
481
  if (!writeCharacteristic) {
450
482
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleCharacteristicNotFound, `Write characteristic not available for ${deviceId}`);
451
483
  }
452
- if (toBuffer.length <= BLE_PACKET_SIZE) {
453
- yield hdShared.wait(UNIFIED_WRITE_DELAY);
454
- yield writeCharacteristicWithAck(deviceId, writeCharacteristic, toBuffer);
484
+ if (toBuffer.length <= packetCapacity) {
485
+ yield writeCharacteristicWithoutResponse(deviceId, writeCharacteristic, toBuffer);
455
486
  return;
456
487
  }
457
488
  for (let offset = 0; offset < toBuffer.length;) {
458
- const chunkSize = Math.min(BLE_PACKET_SIZE, toBuffer.length - offset);
489
+ const chunkSize = Math.min(packetCapacity, toBuffer.length - offset);
459
490
  const chunk = toBuffer.subarray(offset, offset + chunkSize);
460
491
  offset += chunkSize;
461
492
  const latest = doGetWriteCharacteristic();
462
493
  if (!latest) {
463
494
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleCharacteristicNotFound, `Write characteristic not available for ${deviceId}`);
464
495
  }
465
- yield writeCharacteristicWithAck(deviceId, latest, chunk);
466
- if (offset < toBuffer.length) {
467
- yield hdShared.wait(UNIFIED_WRITE_DELAY);
468
- }
496
+ yield writeCharacteristicWithoutResponse(deviceId, latest, chunk);
469
497
  }
470
498
  return;
471
499
  }
472
- if (toBuffer.length <= BLE_PACKET_SIZE) {
473
- yield hdShared.wait(UNIFIED_WRITE_DELAY);
500
+ if (toBuffer.length <= packetCapacity) {
474
501
  yield attemptWindowsWriteUntilPaired(deviceId, doGetWriteCharacteristic, toBuffer, 'single');
475
502
  return;
476
503
  }
477
504
  for (let offset = 0, idx = 0; offset < toBuffer.length; idx++) {
478
- const chunkSize = Math.min(BLE_PACKET_SIZE, toBuffer.length - offset);
505
+ const chunkSize = Math.min(packetCapacity, toBuffer.length - offset);
479
506
  const chunk = toBuffer.subarray(offset, offset + chunkSize);
480
507
  offset += chunkSize;
481
508
  yield attemptWindowsWriteUntilPaired(deviceId, doGetWriteCharacteristic, chunk, `chunk-${idx + 1}`);
482
- if (offset < toBuffer.length) {
483
- yield hdShared.wait(UNIFIED_WRITE_DELAY);
484
- }
485
509
  }
486
510
  });
487
511
  }
@@ -658,22 +682,12 @@ function getDevice(deviceId) {
658
682
  const peripheral = discoveredDevices.get(deviceId);
659
683
  if (peripheral) {
660
684
  const deviceName = ((_a = peripheral.advertisement) === null || _a === void 0 ? void 0 : _a.localName) || 'Unknown Device';
661
- return {
662
- commType: 'electron-ble',
663
- id: peripheral.id,
664
- name: deviceName,
665
- state: peripheral.state || 'disconnected',
666
- };
685
+ return Object.assign({ commType: 'electron-ble', id: peripheral.id, name: deviceName, state: peripheral.state || 'disconnected' }, (typeof peripheral.mtu === 'number' ? { mtu: peripheral.mtu } : {}));
667
686
  }
668
687
  const connectedPeripheral = connectedDevices.get(deviceId);
669
688
  if (connectedPeripheral) {
670
689
  const deviceName = ((_b = connectedPeripheral.advertisement) === null || _b === void 0 ? void 0 : _b.localName) || 'Unknown Device';
671
- return {
672
- commType: 'electron-ble',
673
- id: connectedPeripheral.id,
674
- name: deviceName,
675
- state: connectedPeripheral.state || 'connected',
676
- };
690
+ return Object.assign({ commType: 'electron-ble', id: connectedPeripheral.id, name: deviceName, state: connectedPeripheral.state || 'connected' }, (typeof connectedPeripheral.mtu === 'number' ? { mtu: connectedPeripheral.mtu } : {}));
677
691
  }
678
692
  return {
679
693
  commType: 'electron-ble',
@@ -1 +1 @@
1
- {"version":3,"file":"noble-ble-handler.d.ts","sourceRoot":"","sources":["../src/noble-ble-handler.ts"],"names":[],"mappings":"AA8BA,OAAO,KAAK,EAAsB,WAAW,EAAE,MAAM,UAAU,CAAC;AAi9ChE,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI,CAyJpE"}
1
+ {"version":3,"file":"noble-ble-handler.d.ts","sourceRoot":"","sources":["../src/noble-ble-handler.ts"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAsB,WAAW,EAAE,MAAM,UAAU,CAAC;AA++ChE,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI,CAyJpE"}
@@ -6,6 +6,7 @@ export interface NobleBleAPI {
6
6
  getDevice: (uuid: string) => Promise<{
7
7
  id: string;
8
8
  name: string;
9
+ mtu?: number;
9
10
  } | null>;
10
11
  connect: (uuid: string) => Promise<void>;
11
12
  disconnect: (uuid: string) => Promise<void>;
@@ -13,6 +14,10 @@ export interface NobleBleAPI {
13
14
  unsubscribe: (uuid: string) => Promise<void>;
14
15
  write: (uuid: string, data: string) => Promise<void>;
15
16
  onNotification: (callback: (deviceId: string, data: string) => void) => () => void;
17
+ onMtuChanged?: (callback: (device: {
18
+ id: string;
19
+ mtu: number;
20
+ }) => void) => () => void;
16
21
  onDeviceDisconnected: (callback: (device: {
17
22
  id: string;
18
23
  name: string;
@@ -1 +1 @@
1
- {"version":3,"file":"desktop-api.d.ts","sourceRoot":"","sources":["../../src/types/desktop-api.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC,CAAC;IACzD,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IAC1E,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,cAAc,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,KAAK,MAAM,IAAI,CAAC;IACnF,oBAAoB,EAAE,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,KAAK,MAAM,IAAI,CAAC;IAC/F,iBAAiB,EAAE,MAAM,OAAO,CAAC;QAC/B,SAAS,EAAE,OAAO,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,OAAO,CAAC;QACrB,WAAW,EAAE,OAAO,CAAC;KACtB,CAAC,CAAC;CACJ;AAGD,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,WAAW,CAAC;CACxB"}
1
+ {"version":3,"file":"desktop-api.d.ts","sourceRoot":"","sources":["../../src/types/desktop-api.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC,CAAC;IACzD,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IACxF,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,cAAc,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,KAAK,MAAM,IAAI,CAAC;IACnF,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,KAAK,MAAM,IAAI,CAAC;IACvF,oBAAoB,EAAE,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,KAAK,MAAM,IAAI,CAAC;IAC/F,iBAAiB,EAAE,MAAM,OAAO,CAAC;QAC/B,SAAS,EAAE,OAAO,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,OAAO,CAAC;QACrB,WAAW,EAAE,OAAO,CAAC;KACtB,CAAC,CAAC;CACJ;AAGD,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,WAAW,CAAC;CACxB"}
@@ -4,6 +4,7 @@ export interface DeviceInfo extends OneKeyDeviceInfoBase {
4
4
  id: string;
5
5
  name: string;
6
6
  state: string;
7
+ mtu?: number;
7
8
  }
8
9
  export interface CharacteristicPair {
9
10
  write: Characteristic;
@@ -1 +1 @@
1
- {"version":3,"file":"noble-extended.d.ts","sourceRoot":"","sources":["../../src/types/noble-extended.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAGnE,MAAM,WAAW,UAAW,SAAQ,oBAAoB;IACtD,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAGD,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,cAAc,CAAC;IACtB,MAAM,EAAE,cAAc,CAAC;CACxB;AAGD,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CACX,YAAY,EAAE,MAAM,EAAE,EACtB,eAAe,EAAE,OAAO,EACxB,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,KAAK,IAAI,GACjC,IAAI,CAAC;IACR,YAAY,CAAC,QAAQ,CAAC,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAC1C,EAAE,CAAC,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;IAClE,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,GAAG,IAAI,CAAC;IACxE,cAAc,CAAC,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;IAC9E,cAAc,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,GAAG,IAAI,CAAC;CACrF;AAGD,MAAM,WAAW,MAAM;IACrB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAC5C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAC7C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;CAC9C;AAGD,wBAAgB,OAAO,CACrB,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,EACjC,OAAO,EAAE,MAAM,EACf,GAAG,IAAI,EAAE,GAAG,EAAE,GACb,IAAI,CAMN"}
1
+ {"version":3,"file":"noble-extended.d.ts","sourceRoot":"","sources":["../../src/types/noble-extended.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAGnE,MAAM,WAAW,UAAW,SAAQ,oBAAoB;IACtD,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAGD,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,cAAc,CAAC;IACtB,MAAM,EAAE,cAAc,CAAC;CACxB;AAGD,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,aAAa,CACX,YAAY,EAAE,MAAM,EAAE,EACtB,eAAe,EAAE,OAAO,EACxB,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,KAAK,IAAI,GACjC,IAAI,CAAC;IACR,YAAY,CAAC,QAAQ,CAAC,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAC1C,EAAE,CAAC,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;IAClE,EAAE,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,GAAG,IAAI,CAAC;IACxE,cAAc,CAAC,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;IAC9E,cAAc,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,GAAG,IAAI,CAAC;CACrF;AAGD,MAAM,WAAW,MAAM;IACrB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAC5C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAC7C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;CAC9C;AAGD,wBAAgB,OAAO,CACrB,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,EACjC,OAAO,EAAE,MAAM,EACf,GAAG,IAAI,EAAE,GAAG,EAAE,GACb,IAAI,CAMN"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/hd-transport-electron",
3
- "version": "1.2.0-alpha.68",
3
+ "version": "1.2.0-alpha.69",
4
4
  "author": "OneKey",
5
5
  "homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
6
6
  "license": "MIT",
@@ -25,9 +25,9 @@
25
25
  "electron-log": ">=4.0.0"
26
26
  },
27
27
  "dependencies": {
28
- "@onekeyfe/hd-core": "1.2.0-alpha.68",
29
- "@onekeyfe/hd-shared": "1.2.0-alpha.68",
30
- "@onekeyfe/hd-transport": "1.2.0-alpha.68",
28
+ "@onekeyfe/hd-core": "1.2.0-alpha.69",
29
+ "@onekeyfe/hd-shared": "1.2.0-alpha.69",
30
+ "@onekeyfe/hd-transport": "1.2.0-alpha.69",
31
31
  "@stoprocent/noble": "2.3.16",
32
32
  "p-retry": "^4.6.2"
33
33
  },
@@ -36,5 +36,5 @@
36
36
  "electron": "^25.0.0",
37
37
  "typescript": "^5.3.3"
38
38
  },
39
- "gitHead": "6e8a931d08768980cfe7fa918bba447ed73e2724"
39
+ "gitHead": "c6baed25917e3c3f027f83dfc23cde85400de558"
40
40
  }
@@ -0,0 +1,13 @@
1
+ import { resolveBlePacketCapacity } from '../ble-packet-capacity';
2
+
3
+ describe('resolveBlePacketCapacity', () => {
4
+ test('uses ATT MTU payload capacity with an upper bound', () => {
5
+ expect(resolveBlePacketCapacity(247, 244, 192)).toBe(244);
6
+ expect(resolveBlePacketCapacity(185, 244, 192)).toBe(182);
7
+ });
8
+
9
+ test('preserves the compatibility fallback when MTU is unavailable', () => {
10
+ expect(resolveBlePacketCapacity(null, 244, 192)).toBe(192);
11
+ expect(resolveBlePacketCapacity(undefined, 244, 192)).toBe(192);
12
+ });
13
+ });
@@ -0,0 +1,13 @@
1
+ const BLE_ATT_HEADER_BYTES = 3;
2
+
3
+ export function resolveBlePacketCapacity(
4
+ mtu: number | null | undefined,
5
+ maximumPacketCapacity: number,
6
+ fallbackPacketCapacity: number
7
+ ): number {
8
+ if (typeof mtu !== 'number' || !Number.isFinite(mtu) || mtu <= BLE_ATT_HEADER_BYTES) {
9
+ return fallbackPacketCapacity;
10
+ }
11
+
12
+ return Math.min(maximumPacketCapacity, Math.floor(mtu) - BLE_ATT_HEADER_BYTES);
13
+ }
@@ -21,6 +21,7 @@ import {
21
21
  } from '@onekeyfe/hd-shared';
22
22
  import pRetry from 'p-retry';
23
23
 
24
+ import { resolveBlePacketCapacity } from './ble-packet-capacity';
24
25
  import { safeLog } from './types/noble-extended';
25
26
  import { runBleCallbackOperation, softRefreshSubscription } from './ble-ops';
26
27
  import {
@@ -65,6 +66,10 @@ const deviceDisconnectListeners = new Map<
65
66
  string,
66
67
  { peripheral: Peripheral; listener: () => void }
67
68
  >();
69
+ const deviceMtuListeners = new Map<
70
+ string,
71
+ { peripheral: Peripheral; listener: (mtu: number) => void }
72
+ >();
68
73
 
69
74
  // Windows-only response watchdog state moved to utils/windows-ble-recovery
70
75
 
@@ -86,8 +91,8 @@ const SERVICE_DISCOVERY_TIMEOUT = 10000; // 10 seconds for service discovery
86
91
  const BLE_CLEANUP_TIMEOUT = 250;
87
92
 
88
93
  // Write-related constants
89
- const BLE_PACKET_SIZE = 192;
90
- const UNIFIED_WRITE_DELAY = 5;
94
+ const BLE_PACKET_SIZE_FALLBACK = 192;
95
+ const BLE_PACKET_SIZE_MAXIMUM = 244;
91
96
  const RETRY_CONFIG = { MAX_ATTEMPTS: 15, WRITE_TIMEOUT: 2000 } as const;
92
97
  const IS_WINDOWS = process.platform === 'win32';
93
98
  const ABORTABLE_WRITE_ERROR_PATTERNS = [
@@ -364,6 +369,11 @@ function cleanupDevice(
364
369
  disconnectEntry.peripheral.removeListener('disconnect', disconnectEntry.listener);
365
370
  deviceDisconnectListeners.delete(deviceId);
366
371
  }
372
+ const mtuEntry = deviceMtuListeners.get(deviceId);
373
+ if (mtuEntry) {
374
+ mtuEntry.peripheral.removeListener('mtu', mtuEntry.listener);
375
+ deviceMtuListeners.delete(deviceId);
376
+ }
367
377
  connectedDevices.delete(deviceId);
368
378
  deviceCharacteristics.delete(deviceId);
369
379
  notificationCallbacks.delete(deviceId);
@@ -423,11 +433,33 @@ function setupDisconnectListener(
423
433
  };
424
434
  deviceDisconnectListeners.set(deviceId, { peripheral, listener });
425
435
  peripheral.on('disconnect', listener);
436
+ setupMtuListener(peripheral, deviceId, webContents);
437
+ }
438
+
439
+ function setupMtuListener(
440
+ peripheral: Peripheral,
441
+ deviceId: string,
442
+ webContents: WebContents
443
+ ): void {
444
+ const existing = deviceMtuListeners.get(deviceId);
445
+ if (existing) {
446
+ existing.peripheral.removeListener('mtu', existing.listener);
447
+ }
448
+
449
+ const listener = (mtu: number) => {
450
+ if (!Number.isFinite(mtu) || mtu <= 0) return;
451
+ webContents.send(EOneKeyBleMessageKeys.NOBLE_BLE_MTU_CHANGED, {
452
+ id: deviceId,
453
+ mtu,
454
+ });
455
+ };
456
+ deviceMtuListeners.set(deviceId, { peripheral, listener });
457
+ peripheral.on('mtu', listener);
426
458
  }
427
459
 
428
460
  // ===== Write helpers (inline) =====
429
461
 
430
- async function writeCharacteristicWithAck(
462
+ async function writeCharacteristicWithoutResponse(
431
463
  deviceId: string,
432
464
  writeCharacteristic: Characteristic,
433
465
  buffer: Buffer
@@ -475,7 +507,7 @@ async function attemptWindowsWriteUntilPaired(
475
507
  }
476
508
 
477
509
  try {
478
- await writeCharacteristicWithAck(deviceId, latestWrite, payload);
510
+ await writeCharacteristicWithoutResponse(deviceId, latestWrite, payload);
479
511
  } catch (e) {
480
512
  const errorMessage = e instanceof Error ? e.message : String(e);
481
513
  logger?.error('[BLE-Write] Windows write error', {
@@ -559,6 +591,11 @@ async function transmitHexDataToDevice(deviceId: string, hexData: string): Promi
559
591
 
560
592
  const toBuffer = Buffer.from(hexData, 'hex');
561
593
  const doGetWriteCharacteristic = () => deviceCharacteristics.get(deviceId)?.write;
594
+ const packetCapacity = resolveBlePacketCapacity(
595
+ peripheral.mtu,
596
+ BLE_PACKET_SIZE_MAXIMUM,
597
+ BLE_PACKET_SIZE_FALLBACK
598
+ );
562
599
 
563
600
  if (!IS_WINDOWS || pairedDevices.has(deviceId)) {
564
601
  // macOS / Linux or already paired on Windows: direct write
@@ -569,14 +606,13 @@ async function transmitHexDataToDevice(deviceId: string, hexData: string): Promi
569
606
  `Write characteristic not available for ${deviceId}`
570
607
  );
571
608
  }
572
- if (toBuffer.length <= BLE_PACKET_SIZE) {
573
- await wait(UNIFIED_WRITE_DELAY);
574
- await writeCharacteristicWithAck(deviceId, writeCharacteristic, toBuffer);
609
+ if (toBuffer.length <= packetCapacity) {
610
+ await writeCharacteristicWithoutResponse(deviceId, writeCharacteristic, toBuffer);
575
611
  return;
576
612
  }
577
613
  // chunked
578
614
  for (let offset = 0; offset < toBuffer.length; ) {
579
- const chunkSize = Math.min(BLE_PACKET_SIZE, toBuffer.length - offset);
615
+ const chunkSize = Math.min(packetCapacity, toBuffer.length - offset);
580
616
  const chunk = toBuffer.subarray(offset, offset + chunkSize);
581
617
  offset += chunkSize;
582
618
  const latest = doGetWriteCharacteristic();
@@ -586,23 +622,19 @@ async function transmitHexDataToDevice(deviceId: string, hexData: string): Promi
586
622
  `Write characteristic not available for ${deviceId}`
587
623
  );
588
624
  }
589
- await writeCharacteristicWithAck(deviceId, latest, chunk);
590
- if (offset < toBuffer.length) {
591
- await wait(UNIFIED_WRITE_DELAY);
592
- }
625
+ await writeCharacteristicWithoutResponse(deviceId, latest, chunk);
593
626
  }
594
627
  return;
595
628
  }
596
629
 
597
630
  // Windows unpaired path: use loop
598
- if (toBuffer.length <= BLE_PACKET_SIZE) {
599
- await wait(UNIFIED_WRITE_DELAY);
631
+ if (toBuffer.length <= packetCapacity) {
600
632
  await attemptWindowsWriteUntilPaired(deviceId, doGetWriteCharacteristic, toBuffer, 'single');
601
633
  return;
602
634
  }
603
635
  // chunked loop
604
636
  for (let offset = 0, idx = 0; offset < toBuffer.length; idx++) {
605
- const chunkSize = Math.min(BLE_PACKET_SIZE, toBuffer.length - offset);
637
+ const chunkSize = Math.min(packetCapacity, toBuffer.length - offset);
606
638
  const chunk = toBuffer.subarray(offset, offset + chunkSize);
607
639
  offset += chunkSize;
608
640
  await attemptWindowsWriteUntilPaired(
@@ -611,9 +643,6 @@ async function transmitHexDataToDevice(deviceId: string, hexData: string): Promi
611
643
  chunk,
612
644
  `chunk-${idx + 1}`
613
645
  );
614
- if (offset < toBuffer.length) {
615
- await wait(UNIFIED_WRITE_DELAY);
616
- }
617
646
  }
618
647
  }
619
648
 
@@ -835,6 +864,7 @@ function getDevice(deviceId: string): DeviceInfo | null {
835
864
  id: peripheral.id,
836
865
  name: deviceName,
837
866
  state: peripheral.state || 'disconnected',
867
+ ...(typeof peripheral.mtu === 'number' ? { mtu: peripheral.mtu } : {}),
838
868
  };
839
869
  }
840
870
 
@@ -847,6 +877,7 @@ function getDevice(deviceId: string): DeviceInfo | null {
847
877
  id: connectedPeripheral.id,
848
878
  name: deviceName,
849
879
  state: connectedPeripheral.state || 'connected',
880
+ ...(typeof connectedPeripheral.mtu === 'number' ? { mtu: connectedPeripheral.mtu } : {}),
850
881
  };
851
882
  }
852
883
 
@@ -6,13 +6,14 @@
6
6
  // Noble BLE API interface - core BLE functionality
7
7
  export interface NobleBleAPI {
8
8
  enumerate: () => Promise<{ id: string; name: string }[]>;
9
- getDevice: (uuid: string) => Promise<{ id: string; name: string } | null>;
9
+ getDevice: (uuid: string) => Promise<{ id: string; name: string; mtu?: number } | null>;
10
10
  connect: (uuid: string) => Promise<void>;
11
11
  disconnect: (uuid: string) => Promise<void>;
12
12
  subscribe: (uuid: string) => Promise<void>;
13
13
  unsubscribe: (uuid: string) => Promise<void>;
14
14
  write: (uuid: string, data: string) => Promise<void>;
15
15
  onNotification: (callback: (deviceId: string, data: string) => void) => () => void;
16
+ onMtuChanged?: (callback: (device: { id: string; mtu: number }) => void) => () => void;
16
17
  onDeviceDisconnected: (callback: (device: { id: string; name: string }) => void) => () => void;
17
18
  checkAvailability: () => Promise<{
18
19
  available: boolean;
@@ -11,6 +11,7 @@ export interface DeviceInfo extends OneKeyDeviceInfoBase {
11
11
  id: string;
12
12
  name: string;
13
13
  state: string;
14
+ mtu?: number;
14
15
  }
15
16
 
16
17
  // Characteristic pair interface