@onekeyfe/hd-transport-electron 1.2.8-alpha.117 → 1.2.8-alpha.118
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{index-21e34fdb.js → index-f41d5fc1.js} +2 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +1 -1
- package/dist/{noble-ble-handler-c4530a1b.js → noble-ble-handler-180255d0.js} +27 -6
- package/dist/noble-ble-handler.d.ts.map +1 -1
- package/dist/types/desktop-api.d.ts +1 -0
- package/dist/types/desktop-api.d.ts.map +1 -1
- package/dist/types/noble-extended.d.ts +2 -2
- package/dist/types/noble-extended.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/__tests__/noble-ble-handler.test.ts +235 -0
- package/src/noble-ble-handler.ts +33 -1
- package/src/types/desktop-api.ts +1 -1
- package/src/types/noble-extended.ts +4 -2
|
@@ -55,13 +55,13 @@ function invokeNobleBleIpc(request) {
|
|
|
55
55
|
|
|
56
56
|
function initNobleBleSupport(webContents) {
|
|
57
57
|
return __awaiter(this, void 0, void 0, function* () {
|
|
58
|
-
const { setupNobleBleHandlers } = yield Promise.resolve().then(function () { return require('./noble-ble-handler-
|
|
58
|
+
const { setupNobleBleHandlers } = yield Promise.resolve().then(function () { return require('./noble-ble-handler-180255d0.js'); });
|
|
59
59
|
setupNobleBleHandlers(webContents);
|
|
60
60
|
});
|
|
61
61
|
}
|
|
62
62
|
function disposeNobleBleSupport(releaseNoble) {
|
|
63
63
|
return __awaiter(this, void 0, void 0, function* () {
|
|
64
|
-
const handler = yield Promise.resolve().then(function () { return require('./noble-ble-handler-
|
|
64
|
+
const handler = yield Promise.resolve().then(function () { return require('./noble-ble-handler-180255d0.js'); });
|
|
65
65
|
yield handler.disposeNobleBleSupport(releaseNoble);
|
|
66
66
|
});
|
|
67
67
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { WebContents } from 'electron';
|
|
2
2
|
import { Characteristic, Peripheral } from '@stoprocent/noble';
|
|
3
|
-
import { OneKeyDeviceInfoBase } from '@onekeyfe/hd-transport';
|
|
3
|
+
import { OneKeyDeviceInfoBase, OneKeyMobileDeviceInfo } from '@onekeyfe/hd-transport';
|
|
4
4
|
import { EBleDisconnectReason } from '@onekeyfe/hd-shared';
|
|
5
5
|
|
|
6
|
-
interface DeviceInfo extends OneKeyDeviceInfoBase {
|
|
6
|
+
interface DeviceInfo extends OneKeyDeviceInfoBase, Pick<OneKeyMobileDeviceInfo, 'bleColorCode'> {
|
|
7
7
|
id: string;
|
|
8
8
|
name: string;
|
|
9
9
|
state: string;
|
|
@@ -60,6 +60,7 @@ interface NobleBleAPI {
|
|
|
60
60
|
enumerate: () => Promise<{
|
|
61
61
|
id: string;
|
|
62
62
|
name: string;
|
|
63
|
+
bleColorCode?: string;
|
|
63
64
|
}[]>;
|
|
64
65
|
getDevice: (uuid: string) => Promise<{
|
|
65
66
|
id: string;
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var index = require('./index-
|
|
3
|
+
var index = require('./index-f41d5fc1.js');
|
|
4
4
|
var hdShared = require('@onekeyfe/hd-shared');
|
|
5
5
|
var pRetry = require('p-retry');
|
|
6
6
|
|
|
@@ -771,6 +771,18 @@ function rememberBleName(deviceId, name) {
|
|
|
771
771
|
bleNamesById.set(deviceId, trimmed);
|
|
772
772
|
}
|
|
773
773
|
}
|
|
774
|
+
const bleColorCodesById = new Map();
|
|
775
|
+
function rememberBleColorCode(peripheral) {
|
|
776
|
+
var _a;
|
|
777
|
+
const colorCode = hdShared.parseOnekeyBleColorCode((_a = peripheral.advertisement) === null || _a === void 0 ? void 0 : _a.manufacturerData);
|
|
778
|
+
if (colorCode && bleColorCodesById.get(peripheral.id) !== colorCode) {
|
|
779
|
+
bleColorCodesById.set(peripheral.id, colorCode);
|
|
780
|
+
logger === null || logger === void 0 ? void 0 : logger.debug('[NobleBLE] BLE color code', {
|
|
781
|
+
deviceId: peripheral.id,
|
|
782
|
+
bleColorCode: colorCode,
|
|
783
|
+
});
|
|
784
|
+
}
|
|
785
|
+
}
|
|
774
786
|
function resolveBleName(deviceId) {
|
|
775
787
|
var _a, _b, _c, _d, _e, _f;
|
|
776
788
|
const live = ((_c = (_b = (_a = connectedDevices.get(deviceId)) === null || _a === void 0 ? void 0 : _a.advertisement) === null || _b === void 0 ? void 0 : _b.localName) === null || _c === void 0 ? void 0 : _c.trim()) ||
|
|
@@ -781,18 +793,23 @@ function shouldConnectByIdFirst(deviceId) {
|
|
|
781
793
|
return hdShared.isPro2FamilyBleName(resolveBleName(deviceId));
|
|
782
794
|
}
|
|
783
795
|
function handleDeviceDiscovered(peripheral) {
|
|
784
|
-
var _a, _b, _c;
|
|
796
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
797
|
+
if (hdShared.hasOnekeyCommunicationService((_a = peripheral.advertisement) === null || _a === void 0 ? void 0 : _a.serviceUuids)) {
|
|
798
|
+
rememberBleColorCode(peripheral);
|
|
799
|
+
}
|
|
785
800
|
if (!isOneKeyPeripheral(peripheral)) {
|
|
786
801
|
return;
|
|
787
802
|
}
|
|
788
803
|
const isNewDevice = !discoveredDevices.has(peripheral.id);
|
|
789
804
|
discoveredDevices.set(peripheral.id, peripheral);
|
|
790
|
-
rememberBleName(peripheral.id, (
|
|
805
|
+
rememberBleName(peripheral.id, (_b = peripheral.advertisement) === null || _b === void 0 ? void 0 : _b.localName);
|
|
791
806
|
if (isNewDevice) {
|
|
792
807
|
logger === null || logger === void 0 ? void 0 : logger.debug('[NobleBLE] OneKey BLE device discovered', {
|
|
793
808
|
deviceId: peripheral.id,
|
|
794
|
-
name: ((
|
|
795
|
-
serviceUUIDs: ((
|
|
809
|
+
name: ((_c = peripheral.advertisement) === null || _c === void 0 ? void 0 : _c.localName) || 'Unknown Device',
|
|
810
|
+
serviceUUIDs: ((_d = peripheral.advertisement) === null || _d === void 0 ? void 0 : _d.serviceUuids) || [],
|
|
811
|
+
manufacturerDataLength: (_g = (_f = (_e = peripheral.advertisement) === null || _e === void 0 ? void 0 : _e.manufacturerData) === null || _f === void 0 ? void 0 : _f.length) !== null && _g !== void 0 ? _g : 0,
|
|
812
|
+
bleColorCode: bleColorCodesById.get(peripheral.id),
|
|
796
813
|
});
|
|
797
814
|
}
|
|
798
815
|
}
|
|
@@ -918,6 +935,10 @@ function enumerateDevices(isWindowDestroyed) {
|
|
|
918
935
|
state: peripheral.state || 'disconnected',
|
|
919
936
|
});
|
|
920
937
|
};
|
|
938
|
+
const withBleColorCode = (device) => {
|
|
939
|
+
const bleColorCode = bleColorCodesById.get(device.id);
|
|
940
|
+
return bleColorCode ? Object.assign(Object.assign({}, device), { bleColorCode }) : device;
|
|
941
|
+
};
|
|
921
942
|
const checkDevices = () => {
|
|
922
943
|
discoveredDevices.forEach(pushDevice);
|
|
923
944
|
connectedDevices.forEach(pushDevice);
|
|
@@ -928,7 +949,7 @@ function enumerateDevices(isWindowDestroyed) {
|
|
|
928
949
|
checkDevices();
|
|
929
950
|
yield cleanup();
|
|
930
951
|
logger === null || logger === void 0 ? void 0 : logger.info('[NobleBLE] Scan completed, found devices:', devices.length);
|
|
931
|
-
resolve(devices);
|
|
952
|
+
resolve(devices.map(withBleColorCode));
|
|
932
953
|
}), DEVICE_SCAN_TIMEOUT);
|
|
933
954
|
const cancel = () => cleanup().then(() => resolve([]), reject);
|
|
934
955
|
pendingCancellations.add(cancel);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"noble-ble-handler.d.ts","sourceRoot":"","sources":["../src/noble-ble-handler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"noble-ble-handler.d.ts","sourceRoot":"","sources":["../src/noble-ble-handler.ts"],"names":[],"mappings":"AAkCA,OAAO,KAAK,EAA+B,WAAW,EAAE,MAAM,UAAU,CAAC;AAEzE,OAAO,KAAK,EAAE,wBAAwB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAiC1F,KAAK,mBAAmB,GAAG,KAAK,GAAG;IACjC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,mBAAmB,EAAE,aAAa,SAAK,+CAG3F;AAED,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,OAAO,GAAG,wBAAwB,CAgCvF;AA+KD,wBAAgB,+BAA+B,CAAC,OAAO,CAAC,EAAE,oBAAoB,UAI7E;AAi1DD,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI,CAkOpE;AAOD,wBAAgB,sBAAsB,CACpC,YAAY,GAAE,CAAC,QAAQ,EAAE;IAAE,IAAI,IAAI,IAAI,CAAA;CAAE,KAAK,IAAkC,GAC/E,OAAO,CAAC,IAAI,CAAC,CAiEf"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"desktop-api.d.ts","sourceRoot":"","sources":["../../src/types/desktop-api.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAGhE,MAAM,WAAW,oBAAoB;IACnC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,MAAM,uBAAuB,GAAG;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,IAAI,EAAE,kBAAkB,CAAC;IACzB,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EAAE,uBAAuB,CAAC;CAChC,CAAC;AAEF,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,OAAO,GAChB,QAAQ,IAAI,wBAAwB,CAatC;AAMD,wBAAsB,iBAAiB,CAAC,CAAC,EACvC,OAAO,EAAE,OAAO,CAAC,CAAC,GAAG,wBAAwB,CAAC,GAC7C,OAAO,CAAC,CAAC,CAAC,CAMZ;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"desktop-api.d.ts","sourceRoot":"","sources":["../../src/types/desktop-api.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAGhE,MAAM,WAAW,oBAAoB;IACnC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,MAAM,uBAAuB,GAAG;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,IAAI,EAAE,kBAAkB,CAAC;IACzB,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EAAE,uBAAuB,CAAC;CAChC,CAAC;AAEF,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,OAAO,GAChB,QAAQ,IAAI,wBAAwB,CAatC;AAMD,wBAAsB,iBAAiB,CAAC,CAAC,EACvC,OAAO,EAAE,OAAO,CAAC,CAAC,GAAG,wBAAwB,CAAC,GAC7C,OAAO,CAAC,CAAC,CAAC,CAMZ;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC,CAAC;IAChF,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;IAGzC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACjE,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,EAAE,OAAO,CAAC,EAAE,oBAAoB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrF,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;IAOvF,oBAAoB,EAAE,CACpB,QAAQ,EAAE,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,oBAAoB,CAAA;KAAE,KAAK,IAAI,KACpF,MAAM,IAAI,CAAC;IAChB,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,6 +1,6 @@
|
|
|
1
1
|
import type { Characteristic, Peripheral } from '@stoprocent/noble';
|
|
2
|
-
import type { OneKeyDeviceInfoBase } from '@onekeyfe/hd-transport';
|
|
3
|
-
export interface DeviceInfo extends OneKeyDeviceInfoBase {
|
|
2
|
+
import type { OneKeyDeviceInfoBase, OneKeyMobileDeviceInfo } from '@onekeyfe/hd-transport';
|
|
3
|
+
export interface DeviceInfo extends OneKeyDeviceInfoBase, Pick<OneKeyMobileDeviceInfo, 'bleColorCode'> {
|
|
4
4
|
id: string;
|
|
5
5
|
name: string;
|
|
6
6
|
state: string;
|
|
@@ -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;
|
|
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,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAG3F,MAAM,WAAW,UACf,SAAQ,oBAAoB,EAC1B,IAAI,CAAC,sBAAsB,EAAE,cAAc,CAAC;IAC9C,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,IAAI,IAAI,IAAI,CAAC;IACb,aAAa,CAAC,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,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,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;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.8-alpha.
|
|
3
|
+
"version": "1.2.8-alpha.118",
|
|
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.8-alpha.
|
|
29
|
-
"@onekeyfe/hd-shared": "1.2.8-alpha.
|
|
30
|
-
"@onekeyfe/hd-transport": "1.2.8-alpha.
|
|
28
|
+
"@onekeyfe/hd-core": "1.2.8-alpha.118",
|
|
29
|
+
"@onekeyfe/hd-shared": "1.2.8-alpha.118",
|
|
30
|
+
"@onekeyfe/hd-transport": "1.2.8-alpha.118",
|
|
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": "
|
|
39
|
+
"gitHead": "7b5fe42a7c29ff0aa4c8340c1d5da93026a1b590"
|
|
40
40
|
}
|
|
@@ -1211,3 +1211,238 @@ describe('Noble BLE process shutdown', () => {
|
|
|
1211
1211
|
await sdk.disposeNobleBleSupport();
|
|
1212
1212
|
});
|
|
1213
1213
|
});
|
|
1214
|
+
|
|
1215
|
+
describe('Electron Noble BLE advertisement color', () => {
|
|
1216
|
+
afterEach(() => {
|
|
1217
|
+
jest.useRealTimers();
|
|
1218
|
+
jest.resetModules();
|
|
1219
|
+
jest.clearAllMocks();
|
|
1220
|
+
});
|
|
1221
|
+
|
|
1222
|
+
test('keeps the color of an unnamed advertisement once the scan response names the device', async () => {
|
|
1223
|
+
jest.useFakeTimers({ doNotFake: ['performance'] });
|
|
1224
|
+
|
|
1225
|
+
const handlers = new Map<string, IpcHandler>();
|
|
1226
|
+
const ipcMain = {
|
|
1227
|
+
handle: jest.fn((channel: string, handler: IpcHandler) => {
|
|
1228
|
+
handlers.set(channel, handler);
|
|
1229
|
+
}),
|
|
1230
|
+
removeHandler: jest.fn((channel: string) => {
|
|
1231
|
+
handlers.delete(channel);
|
|
1232
|
+
}),
|
|
1233
|
+
};
|
|
1234
|
+
const noble = new EventEmitter() as EventEmitter & {
|
|
1235
|
+
state: string;
|
|
1236
|
+
startScanning: jest.Mock;
|
|
1237
|
+
stopScanning: jest.Mock;
|
|
1238
|
+
};
|
|
1239
|
+
let resolveScanStarted = () => undefined;
|
|
1240
|
+
const scanStarted = new Promise<void>(resolve => {
|
|
1241
|
+
resolveScanStarted = resolve;
|
|
1242
|
+
});
|
|
1243
|
+
const peripheral = createPeripheral('split-advertisement-device');
|
|
1244
|
+
noble.state = 'poweredOn';
|
|
1245
|
+
noble.startScanning = jest.fn((_services, _duplicates, callback) => {
|
|
1246
|
+
callback?.();
|
|
1247
|
+
// Primary advertisement: services and color, but no name yet.
|
|
1248
|
+
Object.assign(peripheral.advertisement, {
|
|
1249
|
+
manufacturerData: Buffer.from([0x42, 0, 0, 0, 0]),
|
|
1250
|
+
});
|
|
1251
|
+
noble.emit('discover', peripheral);
|
|
1252
|
+
// Scan response: the name arrives, without the manufacturer payload.
|
|
1253
|
+
Object.assign(peripheral.advertisement, {
|
|
1254
|
+
localName: 'Pro 2 A1B2',
|
|
1255
|
+
manufacturerData: Buffer.alloc(0),
|
|
1256
|
+
});
|
|
1257
|
+
noble.emit('discover', peripheral);
|
|
1258
|
+
resolveScanStarted();
|
|
1259
|
+
});
|
|
1260
|
+
noble.stopScanning = jest.fn(callback => callback?.());
|
|
1261
|
+
|
|
1262
|
+
jest.doMock('@stoprocent/noble', () => noble);
|
|
1263
|
+
jest.doMock('electron', () => ({ ipcMain }));
|
|
1264
|
+
jest.doMock('electron-log', () => ({
|
|
1265
|
+
info: jest.fn(),
|
|
1266
|
+
debug: jest.fn(),
|
|
1267
|
+
error: jest.fn(),
|
|
1268
|
+
}));
|
|
1269
|
+
|
|
1270
|
+
const { setupNobleBleHandlers } = await import('../noble-ble-handler');
|
|
1271
|
+
setupNobleBleHandlers({
|
|
1272
|
+
on: jest.fn(),
|
|
1273
|
+
send: jest.fn(),
|
|
1274
|
+
} as unknown as WebContents);
|
|
1275
|
+
|
|
1276
|
+
const enumerate = handlers.get(EOneKeyBleMessageKeys.NOBLE_BLE_ENUMERATE);
|
|
1277
|
+
if (!enumerate) {
|
|
1278
|
+
throw new Error('Electron Noble BLE enumerate handler was not registered');
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1281
|
+
const devicesPromise = Promise.resolve(enumerate());
|
|
1282
|
+
await scanStarted;
|
|
1283
|
+
jest.advanceTimersByTime(5000);
|
|
1284
|
+
|
|
1285
|
+
await expect(devicesPromise).resolves.toEqual([
|
|
1286
|
+
{
|
|
1287
|
+
commType: 'electron-ble',
|
|
1288
|
+
id: 'split-advertisement-device',
|
|
1289
|
+
name: 'Pro 2 A1B2',
|
|
1290
|
+
state: 'disconnected',
|
|
1291
|
+
bleColorCode: 'B',
|
|
1292
|
+
},
|
|
1293
|
+
]);
|
|
1294
|
+
});
|
|
1295
|
+
|
|
1296
|
+
test('applies a color that arrives after the device was listed in the same scan', async () => {
|
|
1297
|
+
jest.useFakeTimers({ doNotFake: ['performance'] });
|
|
1298
|
+
|
|
1299
|
+
const handlers = new Map<string, IpcHandler>();
|
|
1300
|
+
const ipcMain = {
|
|
1301
|
+
handle: jest.fn((channel: string, handler: IpcHandler) => {
|
|
1302
|
+
handlers.set(channel, handler);
|
|
1303
|
+
}),
|
|
1304
|
+
removeHandler: jest.fn((channel: string) => {
|
|
1305
|
+
handlers.delete(channel);
|
|
1306
|
+
}),
|
|
1307
|
+
};
|
|
1308
|
+
const noble = new EventEmitter() as EventEmitter & {
|
|
1309
|
+
state: string;
|
|
1310
|
+
startScanning: jest.Mock;
|
|
1311
|
+
stopScanning: jest.Mock;
|
|
1312
|
+
};
|
|
1313
|
+
let resolveScanStarted = () => undefined;
|
|
1314
|
+
const scanStarted = new Promise<void>(resolve => {
|
|
1315
|
+
resolveScanStarted = resolve;
|
|
1316
|
+
});
|
|
1317
|
+
const peripheral = createPeripheral('late-color-device', 'Neo 1A2B');
|
|
1318
|
+
noble.state = 'poweredOn';
|
|
1319
|
+
noble.startScanning = jest.fn((_services, _duplicates, callback) => {
|
|
1320
|
+
callback?.();
|
|
1321
|
+
Object.assign(peripheral.advertisement, { manufacturerData: Buffer.from([0, 0, 0, 0, 0]) });
|
|
1322
|
+
noble.emit('discover', peripheral);
|
|
1323
|
+
resolveScanStarted();
|
|
1324
|
+
});
|
|
1325
|
+
noble.stopScanning = jest.fn(callback => callback?.());
|
|
1326
|
+
|
|
1327
|
+
jest.doMock('@stoprocent/noble', () => noble);
|
|
1328
|
+
jest.doMock('electron', () => ({ ipcMain }));
|
|
1329
|
+
jest.doMock('electron-log', () => ({
|
|
1330
|
+
info: jest.fn(),
|
|
1331
|
+
debug: jest.fn(),
|
|
1332
|
+
error: jest.fn(),
|
|
1333
|
+
}));
|
|
1334
|
+
|
|
1335
|
+
const { setupNobleBleHandlers } = await import('../noble-ble-handler');
|
|
1336
|
+
setupNobleBleHandlers({
|
|
1337
|
+
on: jest.fn(),
|
|
1338
|
+
send: jest.fn(),
|
|
1339
|
+
} as unknown as WebContents);
|
|
1340
|
+
|
|
1341
|
+
const enumerate = handlers.get(EOneKeyBleMessageKeys.NOBLE_BLE_ENUMERATE);
|
|
1342
|
+
if (!enumerate) {
|
|
1343
|
+
throw new Error('Electron Noble BLE enumerate handler was not registered');
|
|
1344
|
+
}
|
|
1345
|
+
|
|
1346
|
+
const devicesPromise = Promise.resolve(enumerate());
|
|
1347
|
+
await scanStarted;
|
|
1348
|
+
// The first periodic check lists the device before its color is advertised.
|
|
1349
|
+
jest.advanceTimersByTime(600);
|
|
1350
|
+
Object.assign(peripheral.advertisement, {
|
|
1351
|
+
manufacturerData: Buffer.from([0x45, 0, 0, 0, 0]),
|
|
1352
|
+
});
|
|
1353
|
+
noble.emit('discover', peripheral);
|
|
1354
|
+
jest.advanceTimersByTime(5000);
|
|
1355
|
+
|
|
1356
|
+
await expect(devicesPromise).resolves.toEqual([
|
|
1357
|
+
{
|
|
1358
|
+
commType: 'electron-ble',
|
|
1359
|
+
id: 'late-color-device',
|
|
1360
|
+
name: 'Neo 1A2B',
|
|
1361
|
+
state: 'disconnected',
|
|
1362
|
+
bleColorCode: 'E',
|
|
1363
|
+
},
|
|
1364
|
+
]);
|
|
1365
|
+
});
|
|
1366
|
+
|
|
1367
|
+
test('keeps the advertised color after Noble overwrites the manufacturer data', async () => {
|
|
1368
|
+
jest.useFakeTimers({ doNotFake: ['performance'] });
|
|
1369
|
+
|
|
1370
|
+
const handlers = new Map<string, IpcHandler>();
|
|
1371
|
+
const ipcMain = {
|
|
1372
|
+
handle: jest.fn((channel: string, handler: IpcHandler) => {
|
|
1373
|
+
handlers.set(channel, handler);
|
|
1374
|
+
}),
|
|
1375
|
+
removeHandler: jest.fn((channel: string) => {
|
|
1376
|
+
handlers.delete(channel);
|
|
1377
|
+
}),
|
|
1378
|
+
};
|
|
1379
|
+
const noble = new EventEmitter() as EventEmitter & {
|
|
1380
|
+
state: string;
|
|
1381
|
+
startScanning: jest.Mock;
|
|
1382
|
+
stopScanning: jest.Mock;
|
|
1383
|
+
};
|
|
1384
|
+
let resolveScanStarted = () => undefined;
|
|
1385
|
+
const scanStarted = new Promise<void>(resolve => {
|
|
1386
|
+
resolveScanStarted = resolve;
|
|
1387
|
+
});
|
|
1388
|
+
const coloredPeripheral = createPeripheral('colored-device', 'Pro 2 A1B2');
|
|
1389
|
+
const legacyPeripheral = createPeripheral('legacy-device', 'Pro 2 C3D4');
|
|
1390
|
+
noble.state = 'poweredOn';
|
|
1391
|
+
noble.startScanning = jest.fn((_services, _duplicates, callback) => {
|
|
1392
|
+
callback?.();
|
|
1393
|
+
Object.assign(coloredPeripheral.advertisement, {
|
|
1394
|
+
manufacturerData: Buffer.from([0x44, 0, 0, 0, 0]),
|
|
1395
|
+
});
|
|
1396
|
+
noble.emit('discover', coloredPeripheral);
|
|
1397
|
+
// macOS and Windows replace the stored payload with an empty buffer when a
|
|
1398
|
+
// later event carries no 0xFF section.
|
|
1399
|
+
Object.assign(coloredPeripheral.advertisement, { manufacturerData: Buffer.alloc(0) });
|
|
1400
|
+
noble.emit('discover', coloredPeripheral);
|
|
1401
|
+
Object.assign(legacyPeripheral.advertisement, {
|
|
1402
|
+
manufacturerData: Buffer.from([0, 0, 0, 0]),
|
|
1403
|
+
});
|
|
1404
|
+
noble.emit('discover', legacyPeripheral);
|
|
1405
|
+
resolveScanStarted();
|
|
1406
|
+
});
|
|
1407
|
+
noble.stopScanning = jest.fn(callback => callback?.());
|
|
1408
|
+
|
|
1409
|
+
jest.doMock('@stoprocent/noble', () => noble);
|
|
1410
|
+
jest.doMock('electron', () => ({ ipcMain }));
|
|
1411
|
+
jest.doMock('electron-log', () => ({
|
|
1412
|
+
info: jest.fn(),
|
|
1413
|
+
debug: jest.fn(),
|
|
1414
|
+
error: jest.fn(),
|
|
1415
|
+
}));
|
|
1416
|
+
|
|
1417
|
+
const { setupNobleBleHandlers } = await import('../noble-ble-handler');
|
|
1418
|
+
setupNobleBleHandlers({
|
|
1419
|
+
on: jest.fn(),
|
|
1420
|
+
send: jest.fn(),
|
|
1421
|
+
} as unknown as WebContents);
|
|
1422
|
+
|
|
1423
|
+
const enumerate = handlers.get(EOneKeyBleMessageKeys.NOBLE_BLE_ENUMERATE);
|
|
1424
|
+
if (!enumerate) {
|
|
1425
|
+
throw new Error('Electron Noble BLE enumerate handler was not registered');
|
|
1426
|
+
}
|
|
1427
|
+
|
|
1428
|
+
const devicesPromise = Promise.resolve(enumerate());
|
|
1429
|
+
await scanStarted;
|
|
1430
|
+
jest.advanceTimersByTime(5000);
|
|
1431
|
+
|
|
1432
|
+
await expect(devicesPromise).resolves.toEqual([
|
|
1433
|
+
{
|
|
1434
|
+
commType: 'electron-ble',
|
|
1435
|
+
id: 'colored-device',
|
|
1436
|
+
name: 'Pro 2 A1B2',
|
|
1437
|
+
state: 'disconnected',
|
|
1438
|
+
bleColorCode: 'D',
|
|
1439
|
+
},
|
|
1440
|
+
{
|
|
1441
|
+
commType: 'electron-ble',
|
|
1442
|
+
id: 'legacy-device',
|
|
1443
|
+
name: 'Pro 2 C3D4',
|
|
1444
|
+
state: 'disconnected',
|
|
1445
|
+
},
|
|
1446
|
+
]);
|
|
1447
|
+
});
|
|
1448
|
+
});
|
package/src/noble-ble-handler.ts
CHANGED
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
isOnekeyBluetoothDevice,
|
|
20
20
|
isPro2FamilyBleName,
|
|
21
21
|
matchesKnownBleUuid,
|
|
22
|
+
parseOnekeyBleColorCode,
|
|
22
23
|
wait,
|
|
23
24
|
} from '@onekeyfe/hd-shared';
|
|
24
25
|
import pRetry from 'p-retry';
|
|
@@ -1012,6 +1013,22 @@ function rememberBleName(deviceId: string, name?: string | null): void {
|
|
|
1012
1013
|
}
|
|
1013
1014
|
}
|
|
1014
1015
|
|
|
1016
|
+
// Noble reuses one Peripheral per id, and on macOS/Windows an event without 0xFF data
|
|
1017
|
+
// replaces manufacturerData with an empty buffer. Snapshot the color when the OneKey
|
|
1018
|
+
// advertisement is seen; it is kept like the name because a linked device stops advertising.
|
|
1019
|
+
const bleColorCodesById = new Map<string, string>();
|
|
1020
|
+
|
|
1021
|
+
function rememberBleColorCode(peripheral: Peripheral): void {
|
|
1022
|
+
const colorCode = parseOnekeyBleColorCode(peripheral.advertisement?.manufacturerData);
|
|
1023
|
+
if (colorCode && bleColorCodesById.get(peripheral.id) !== colorCode) {
|
|
1024
|
+
bleColorCodesById.set(peripheral.id, colorCode);
|
|
1025
|
+
logger?.debug('[NobleBLE] BLE color code', {
|
|
1026
|
+
deviceId: peripheral.id,
|
|
1027
|
+
bleColorCode: colorCode,
|
|
1028
|
+
});
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
|
|
1015
1032
|
function resolveBleName(deviceId: string): string | undefined {
|
|
1016
1033
|
const live =
|
|
1017
1034
|
connectedDevices.get(deviceId)?.advertisement?.localName?.trim() ||
|
|
@@ -1031,6 +1048,12 @@ function shouldConnectByIdFirst(deviceId: string): boolean {
|
|
|
1031
1048
|
}
|
|
1032
1049
|
|
|
1033
1050
|
function handleDeviceDiscovered(peripheral: Peripheral): void {
|
|
1051
|
+
// The color rides in the primary advertisement while the name may only come
|
|
1052
|
+
// in a later scan response, so record it before the name-dependent filter.
|
|
1053
|
+
if (hasOnekeyCommunicationService(peripheral.advertisement?.serviceUuids)) {
|
|
1054
|
+
rememberBleColorCode(peripheral);
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1034
1057
|
// Only process OneKey candidates for general discovery. Avoid logging every
|
|
1035
1058
|
// ambient BLE peripheral; it makes Pro2 debugging hard to read.
|
|
1036
1059
|
if (!isOneKeyPeripheral(peripheral)) {
|
|
@@ -1045,6 +1068,9 @@ function handleDeviceDiscovered(peripheral: Peripheral): void {
|
|
|
1045
1068
|
deviceId: peripheral.id,
|
|
1046
1069
|
name: peripheral.advertisement?.localName || 'Unknown Device',
|
|
1047
1070
|
serviceUUIDs: peripheral.advertisement?.serviceUuids || [],
|
|
1071
|
+
// 5 = advertises a color slot; 4 = BLE firmware before 1.0.23.
|
|
1072
|
+
manufacturerDataLength: peripheral.advertisement?.manufacturerData?.length ?? 0,
|
|
1073
|
+
bleColorCode: bleColorCodesById.get(peripheral.id),
|
|
1048
1074
|
});
|
|
1049
1075
|
}
|
|
1050
1076
|
}
|
|
@@ -1200,6 +1226,12 @@ async function enumerateDevices(isWindowDestroyed: () => boolean): Promise<Devic
|
|
|
1200
1226
|
state: peripheral.state || 'disconnected',
|
|
1201
1227
|
});
|
|
1202
1228
|
};
|
|
1229
|
+
// A device kept from an earlier round is pushed before this round's
|
|
1230
|
+
// advertisements arrive, so apply colors when the scan resolves.
|
|
1231
|
+
const withBleColorCode = (device: DeviceInfo): DeviceInfo => {
|
|
1232
|
+
const bleColorCode = bleColorCodesById.get(device.id);
|
|
1233
|
+
return bleColorCode ? { ...device, bleColorCode } : device;
|
|
1234
|
+
};
|
|
1203
1235
|
const checkDevices = () => {
|
|
1204
1236
|
discoveredDevices.forEach(pushDevice);
|
|
1205
1237
|
// A linked device stops advertising, so the scan never rediscovers it.
|
|
@@ -1213,7 +1245,7 @@ async function enumerateDevices(isWindowDestroyed: () => boolean): Promise<Devic
|
|
|
1213
1245
|
checkDevices();
|
|
1214
1246
|
await cleanup();
|
|
1215
1247
|
logger?.info('[NobleBLE] Scan completed, found devices:', devices.length);
|
|
1216
|
-
resolve(devices);
|
|
1248
|
+
resolve(devices.map(withBleColorCode));
|
|
1217
1249
|
}, DEVICE_SCAN_TIMEOUT);
|
|
1218
1250
|
|
|
1219
1251
|
const cancel = () => cleanup().then(() => resolve([]), reject);
|
package/src/types/desktop-api.ts
CHANGED
|
@@ -55,7 +55,7 @@ export async function invokeNobleBleIpc<T>(
|
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
export interface NobleBleAPI {
|
|
58
|
-
enumerate: () => Promise<{ id: string; name: string }[]>;
|
|
58
|
+
enumerate: () => Promise<{ id: string; name: string; bleColorCode?: string }[]>;
|
|
59
59
|
getDevice: (uuid: string) => Promise<{ id: string; name: string; mtu?: number } | null>;
|
|
60
60
|
connect: (uuid: string) => Promise<void>;
|
|
61
61
|
// Logical end-of-operation: link stays up, idle countdown starts. Optional —
|
|
@@ -4,10 +4,12 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import type { Characteristic, Peripheral } from '@stoprocent/noble';
|
|
7
|
-
import type { OneKeyDeviceInfoBase } from '@onekeyfe/hd-transport';
|
|
7
|
+
import type { OneKeyDeviceInfoBase, OneKeyMobileDeviceInfo } from '@onekeyfe/hd-transport';
|
|
8
8
|
|
|
9
9
|
// Device info interface for our API
|
|
10
|
-
export interface DeviceInfo
|
|
10
|
+
export interface DeviceInfo
|
|
11
|
+
extends OneKeyDeviceInfoBase,
|
|
12
|
+
Pick<OneKeyMobileDeviceInfo, 'bleColorCode'> {
|
|
11
13
|
id: string;
|
|
12
14
|
name: string;
|
|
13
15
|
state: string;
|