@onekeyfe/hwk-desktop-noble-ble 1.2.6-alpha.0 → 1.2.8-alpha.101
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/{chunk-A5AENDC2.mjs → chunk-ILABAQJY.mjs} +4 -2
- package/dist/{chunk-A5AENDC2.mjs.map → chunk-ILABAQJY.mjs.map} +1 -1
- package/dist/constants.d.mts +3 -1
- package/dist/constants.d.ts +3 -1
- package/dist/constants.js +5 -2
- package/dist/constants.js.map +1 -1
- package/dist/constants.mjs +5 -3
- package/dist/index.d.mts +32 -3
- package/dist/index.d.ts +32 -3
- package/dist/index.js +104 -22
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +104 -23
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -4
|
@@ -27,6 +27,7 @@ var THIRD_PARTY_BLE_SCAN_DURATION_MS = 5e3;
|
|
|
27
27
|
var THIRD_PARTY_BLE_SCAN_IDLE_STOP_MS = 1e4;
|
|
28
28
|
var THIRD_PARTY_BLE_DEVICE_TTL_MS = 5e3;
|
|
29
29
|
var THIRD_PARTY_BLE_POWER_ON_TIMEOUT_MS = 1e4;
|
|
30
|
+
var THIRD_PARTY_BLE_STATE_SETTLE_TIMEOUT_MS = 3e3;
|
|
30
31
|
|
|
31
32
|
export {
|
|
32
33
|
__require,
|
|
@@ -34,6 +35,7 @@ export {
|
|
|
34
35
|
THIRD_PARTY_BLE_SCAN_DURATION_MS,
|
|
35
36
|
THIRD_PARTY_BLE_SCAN_IDLE_STOP_MS,
|
|
36
37
|
THIRD_PARTY_BLE_DEVICE_TTL_MS,
|
|
37
|
-
THIRD_PARTY_BLE_POWER_ON_TIMEOUT_MS
|
|
38
|
+
THIRD_PARTY_BLE_POWER_ON_TIMEOUT_MS,
|
|
39
|
+
THIRD_PARTY_BLE_STATE_SETTLE_TIMEOUT_MS
|
|
38
40
|
};
|
|
39
|
-
//# sourceMappingURL=chunk-
|
|
41
|
+
//# sourceMappingURL=chunk-ILABAQJY.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/constants.ts"],"sourcesContent":["/**\n * Renderer/main IPC channels shared by every third-party BLE vendor; prefixed to\n * avoid clashing with the OneKey handler (`$onekey-noble-ble-*`) in one app.\n */\nexport const THIRD_PARTY_BLE_CHANNELS = {\n scan: '$onekey-3p-ble-scan',\n stopScan: '$onekey-3p-ble-stop-scan',\n connect: '$onekey-3p-ble-connect',\n disconnect: '$onekey-3p-ble-disconnect',\n write: '$onekey-3p-ble-write',\n subscribe: '$onekey-3p-ble-subscribe',\n unsubscribe: '$onekey-3p-ble-unsubscribe',\n availability: '$onekey-3p-ble-availability',\n getDevice: '$onekey-3p-ble-get-device',\n readRssi: '$onekey-3p-ble-read-rssi',\n cancelPairing: '$onekey-3p-ble-cancel-pairing',\n /** push event: main → renderer with assembled BLE notification payload */\n notification: '$onekey-3p-ble-notification',\n /** push event: main → renderer when device disconnects unexpectedly */\n disconnected: '$onekey-3p-ble-disconnected',\n} as const;\n\nexport type ThirdPartyBleChannel =\n (typeof THIRD_PARTY_BLE_CHANNELS)[keyof typeof THIRD_PARTY_BLE_CHANNELS];\n\n/** Reconnect scan window for `connect(id)`. */\nexport const THIRD_PARTY_BLE_SCAN_DURATION_MS = 5_000;\n\n/** Continuous scan auto-stops this long after the last poll (reset, not accumulated). */\nexport const THIRD_PARTY_BLE_SCAN_IDLE_STOP_MS = 10_000;\n\n/** Drop a device from the snapshot if it hasn't re-advertised within this window. */\nexport const THIRD_PARTY_BLE_DEVICE_TTL_MS = 5_000;\n\n/** Time we'll wait for noble to reach `poweredOn` before failing init. */\nexport const THIRD_PARTY_BLE_POWER_ON_TIMEOUT_MS = 10_000;\n"],"mappings":";;;;;;;;AAIO,IAAM,2BAA2B;AAAA,EACtC,MAAM;AAAA,EACN,UAAU;AAAA,EACV,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,OAAO;AAAA,EACP,WAAW;AAAA,EACX,aAAa;AAAA,EACb,cAAc;AAAA,EACd,WAAW;AAAA,EACX,UAAU;AAAA,EACV,eAAe;AAAA;AAAA,EAEf,cAAc;AAAA;AAAA,EAEd,cAAc;AAChB;AAMO,IAAM,mCAAmC;AAGzC,IAAM,oCAAoC;AAG1C,IAAM,gCAAgC;AAGtC,IAAM,sCAAsC;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts"],"sourcesContent":["/**\n * Renderer/main IPC channels shared by every third-party BLE vendor; prefixed to\n * avoid clashing with the OneKey handler (`$onekey-noble-ble-*`) in one app.\n */\nexport const THIRD_PARTY_BLE_CHANNELS = {\n scan: '$onekey-3p-ble-scan',\n stopScan: '$onekey-3p-ble-stop-scan',\n connect: '$onekey-3p-ble-connect',\n disconnect: '$onekey-3p-ble-disconnect',\n write: '$onekey-3p-ble-write',\n subscribe: '$onekey-3p-ble-subscribe',\n unsubscribe: '$onekey-3p-ble-unsubscribe',\n availability: '$onekey-3p-ble-availability',\n getDevice: '$onekey-3p-ble-get-device',\n readRssi: '$onekey-3p-ble-read-rssi',\n cancelPairing: '$onekey-3p-ble-cancel-pairing',\n /** push event: main → renderer with assembled BLE notification payload */\n notification: '$onekey-3p-ble-notification',\n /** push event: main → renderer when device disconnects unexpectedly */\n disconnected: '$onekey-3p-ble-disconnected',\n} as const;\n\nexport type ThirdPartyBleChannel =\n (typeof THIRD_PARTY_BLE_CHANNELS)[keyof typeof THIRD_PARTY_BLE_CHANNELS];\n\n/** Reconnect scan window for `connect(id)`. */\nexport const THIRD_PARTY_BLE_SCAN_DURATION_MS = 5_000;\n\n/** Continuous scan auto-stops this long after the last poll (reset, not accumulated). */\nexport const THIRD_PARTY_BLE_SCAN_IDLE_STOP_MS = 10_000;\n\n/** Drop a device from the snapshot if it hasn't re-advertised within this window. */\nexport const THIRD_PARTY_BLE_DEVICE_TTL_MS = 5_000;\n\n/** Time we'll wait for noble to reach `poweredOn` before failing init. */\nexport const THIRD_PARTY_BLE_POWER_ON_TIMEOUT_MS = 10_000;\n\n/** Time an availability check waits for a fresh noble to report its first state. */\nexport const THIRD_PARTY_BLE_STATE_SETTLE_TIMEOUT_MS = 3_000;\n"],"mappings":";;;;;;;;AAIO,IAAM,2BAA2B;AAAA,EACtC,MAAM;AAAA,EACN,UAAU;AAAA,EACV,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,OAAO;AAAA,EACP,WAAW;AAAA,EACX,aAAa;AAAA,EACb,cAAc;AAAA,EACd,WAAW;AAAA,EACX,UAAU;AAAA,EACV,eAAe;AAAA;AAAA,EAEf,cAAc;AAAA;AAAA,EAEd,cAAc;AAChB;AAMO,IAAM,mCAAmC;AAGzC,IAAM,oCAAoC;AAG1C,IAAM,gCAAgC;AAGtC,IAAM,sCAAsC;AAG5C,IAAM,0CAA0C;","names":[]}
|
package/dist/constants.d.mts
CHANGED
|
@@ -28,5 +28,7 @@ declare const THIRD_PARTY_BLE_SCAN_IDLE_STOP_MS = 10000;
|
|
|
28
28
|
declare const THIRD_PARTY_BLE_DEVICE_TTL_MS = 5000;
|
|
29
29
|
/** Time we'll wait for noble to reach `poweredOn` before failing init. */
|
|
30
30
|
declare const THIRD_PARTY_BLE_POWER_ON_TIMEOUT_MS = 10000;
|
|
31
|
+
/** Time an availability check waits for a fresh noble to report its first state. */
|
|
32
|
+
declare const THIRD_PARTY_BLE_STATE_SETTLE_TIMEOUT_MS = 3000;
|
|
31
33
|
|
|
32
|
-
export { THIRD_PARTY_BLE_CHANNELS, THIRD_PARTY_BLE_DEVICE_TTL_MS, THIRD_PARTY_BLE_POWER_ON_TIMEOUT_MS, THIRD_PARTY_BLE_SCAN_DURATION_MS, THIRD_PARTY_BLE_SCAN_IDLE_STOP_MS, type ThirdPartyBleChannel };
|
|
34
|
+
export { THIRD_PARTY_BLE_CHANNELS, THIRD_PARTY_BLE_DEVICE_TTL_MS, THIRD_PARTY_BLE_POWER_ON_TIMEOUT_MS, THIRD_PARTY_BLE_SCAN_DURATION_MS, THIRD_PARTY_BLE_SCAN_IDLE_STOP_MS, THIRD_PARTY_BLE_STATE_SETTLE_TIMEOUT_MS, type ThirdPartyBleChannel };
|
package/dist/constants.d.ts
CHANGED
|
@@ -28,5 +28,7 @@ declare const THIRD_PARTY_BLE_SCAN_IDLE_STOP_MS = 10000;
|
|
|
28
28
|
declare const THIRD_PARTY_BLE_DEVICE_TTL_MS = 5000;
|
|
29
29
|
/** Time we'll wait for noble to reach `poweredOn` before failing init. */
|
|
30
30
|
declare const THIRD_PARTY_BLE_POWER_ON_TIMEOUT_MS = 10000;
|
|
31
|
+
/** Time an availability check waits for a fresh noble to report its first state. */
|
|
32
|
+
declare const THIRD_PARTY_BLE_STATE_SETTLE_TIMEOUT_MS = 3000;
|
|
31
33
|
|
|
32
|
-
export { THIRD_PARTY_BLE_CHANNELS, THIRD_PARTY_BLE_DEVICE_TTL_MS, THIRD_PARTY_BLE_POWER_ON_TIMEOUT_MS, THIRD_PARTY_BLE_SCAN_DURATION_MS, THIRD_PARTY_BLE_SCAN_IDLE_STOP_MS, type ThirdPartyBleChannel };
|
|
34
|
+
export { THIRD_PARTY_BLE_CHANNELS, THIRD_PARTY_BLE_DEVICE_TTL_MS, THIRD_PARTY_BLE_POWER_ON_TIMEOUT_MS, THIRD_PARTY_BLE_SCAN_DURATION_MS, THIRD_PARTY_BLE_SCAN_IDLE_STOP_MS, THIRD_PARTY_BLE_STATE_SETTLE_TIMEOUT_MS, type ThirdPartyBleChannel };
|
package/dist/constants.js
CHANGED
|
@@ -24,7 +24,8 @@ __export(constants_exports, {
|
|
|
24
24
|
THIRD_PARTY_BLE_DEVICE_TTL_MS: () => THIRD_PARTY_BLE_DEVICE_TTL_MS,
|
|
25
25
|
THIRD_PARTY_BLE_POWER_ON_TIMEOUT_MS: () => THIRD_PARTY_BLE_POWER_ON_TIMEOUT_MS,
|
|
26
26
|
THIRD_PARTY_BLE_SCAN_DURATION_MS: () => THIRD_PARTY_BLE_SCAN_DURATION_MS,
|
|
27
|
-
THIRD_PARTY_BLE_SCAN_IDLE_STOP_MS: () => THIRD_PARTY_BLE_SCAN_IDLE_STOP_MS
|
|
27
|
+
THIRD_PARTY_BLE_SCAN_IDLE_STOP_MS: () => THIRD_PARTY_BLE_SCAN_IDLE_STOP_MS,
|
|
28
|
+
THIRD_PARTY_BLE_STATE_SETTLE_TIMEOUT_MS: () => THIRD_PARTY_BLE_STATE_SETTLE_TIMEOUT_MS
|
|
28
29
|
});
|
|
29
30
|
module.exports = __toCommonJS(constants_exports);
|
|
30
31
|
var THIRD_PARTY_BLE_CHANNELS = {
|
|
@@ -48,12 +49,14 @@ var THIRD_PARTY_BLE_SCAN_DURATION_MS = 5e3;
|
|
|
48
49
|
var THIRD_PARTY_BLE_SCAN_IDLE_STOP_MS = 1e4;
|
|
49
50
|
var THIRD_PARTY_BLE_DEVICE_TTL_MS = 5e3;
|
|
50
51
|
var THIRD_PARTY_BLE_POWER_ON_TIMEOUT_MS = 1e4;
|
|
52
|
+
var THIRD_PARTY_BLE_STATE_SETTLE_TIMEOUT_MS = 3e3;
|
|
51
53
|
// Annotate the CommonJS export names for ESM import in node:
|
|
52
54
|
0 && (module.exports = {
|
|
53
55
|
THIRD_PARTY_BLE_CHANNELS,
|
|
54
56
|
THIRD_PARTY_BLE_DEVICE_TTL_MS,
|
|
55
57
|
THIRD_PARTY_BLE_POWER_ON_TIMEOUT_MS,
|
|
56
58
|
THIRD_PARTY_BLE_SCAN_DURATION_MS,
|
|
57
|
-
THIRD_PARTY_BLE_SCAN_IDLE_STOP_MS
|
|
59
|
+
THIRD_PARTY_BLE_SCAN_IDLE_STOP_MS,
|
|
60
|
+
THIRD_PARTY_BLE_STATE_SETTLE_TIMEOUT_MS
|
|
58
61
|
});
|
|
59
62
|
//# sourceMappingURL=constants.js.map
|
package/dist/constants.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/constants.ts"],"sourcesContent":["/**\n * Renderer/main IPC channels shared by every third-party BLE vendor; prefixed to\n * avoid clashing with the OneKey handler (`$onekey-noble-ble-*`) in one app.\n */\nexport const THIRD_PARTY_BLE_CHANNELS = {\n scan: '$onekey-3p-ble-scan',\n stopScan: '$onekey-3p-ble-stop-scan',\n connect: '$onekey-3p-ble-connect',\n disconnect: '$onekey-3p-ble-disconnect',\n write: '$onekey-3p-ble-write',\n subscribe: '$onekey-3p-ble-subscribe',\n unsubscribe: '$onekey-3p-ble-unsubscribe',\n availability: '$onekey-3p-ble-availability',\n getDevice: '$onekey-3p-ble-get-device',\n readRssi: '$onekey-3p-ble-read-rssi',\n cancelPairing: '$onekey-3p-ble-cancel-pairing',\n /** push event: main → renderer with assembled BLE notification payload */\n notification: '$onekey-3p-ble-notification',\n /** push event: main → renderer when device disconnects unexpectedly */\n disconnected: '$onekey-3p-ble-disconnected',\n} as const;\n\nexport type ThirdPartyBleChannel =\n (typeof THIRD_PARTY_BLE_CHANNELS)[keyof typeof THIRD_PARTY_BLE_CHANNELS];\n\n/** Reconnect scan window for `connect(id)`. */\nexport const THIRD_PARTY_BLE_SCAN_DURATION_MS = 5_000;\n\n/** Continuous scan auto-stops this long after the last poll (reset, not accumulated). */\nexport const THIRD_PARTY_BLE_SCAN_IDLE_STOP_MS = 10_000;\n\n/** Drop a device from the snapshot if it hasn't re-advertised within this window. */\nexport const THIRD_PARTY_BLE_DEVICE_TTL_MS = 5_000;\n\n/** Time we'll wait for noble to reach `poweredOn` before failing init. */\nexport const THIRD_PARTY_BLE_POWER_ON_TIMEOUT_MS = 10_000;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIO,IAAM,2BAA2B;AAAA,EACtC,MAAM;AAAA,EACN,UAAU;AAAA,EACV,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,OAAO;AAAA,EACP,WAAW;AAAA,EACX,aAAa;AAAA,EACb,cAAc;AAAA,EACd,WAAW;AAAA,EACX,UAAU;AAAA,EACV,eAAe;AAAA;AAAA,EAEf,cAAc;AAAA;AAAA,EAEd,cAAc;AAChB;AAMO,IAAM,mCAAmC;AAGzC,IAAM,oCAAoC;AAG1C,IAAM,gCAAgC;AAGtC,IAAM,sCAAsC;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts"],"sourcesContent":["/**\n * Renderer/main IPC channels shared by every third-party BLE vendor; prefixed to\n * avoid clashing with the OneKey handler (`$onekey-noble-ble-*`) in one app.\n */\nexport const THIRD_PARTY_BLE_CHANNELS = {\n scan: '$onekey-3p-ble-scan',\n stopScan: '$onekey-3p-ble-stop-scan',\n connect: '$onekey-3p-ble-connect',\n disconnect: '$onekey-3p-ble-disconnect',\n write: '$onekey-3p-ble-write',\n subscribe: '$onekey-3p-ble-subscribe',\n unsubscribe: '$onekey-3p-ble-unsubscribe',\n availability: '$onekey-3p-ble-availability',\n getDevice: '$onekey-3p-ble-get-device',\n readRssi: '$onekey-3p-ble-read-rssi',\n cancelPairing: '$onekey-3p-ble-cancel-pairing',\n /** push event: main → renderer with assembled BLE notification payload */\n notification: '$onekey-3p-ble-notification',\n /** push event: main → renderer when device disconnects unexpectedly */\n disconnected: '$onekey-3p-ble-disconnected',\n} as const;\n\nexport type ThirdPartyBleChannel =\n (typeof THIRD_PARTY_BLE_CHANNELS)[keyof typeof THIRD_PARTY_BLE_CHANNELS];\n\n/** Reconnect scan window for `connect(id)`. */\nexport const THIRD_PARTY_BLE_SCAN_DURATION_MS = 5_000;\n\n/** Continuous scan auto-stops this long after the last poll (reset, not accumulated). */\nexport const THIRD_PARTY_BLE_SCAN_IDLE_STOP_MS = 10_000;\n\n/** Drop a device from the snapshot if it hasn't re-advertised within this window. */\nexport const THIRD_PARTY_BLE_DEVICE_TTL_MS = 5_000;\n\n/** Time we'll wait for noble to reach `poweredOn` before failing init. */\nexport const THIRD_PARTY_BLE_POWER_ON_TIMEOUT_MS = 10_000;\n\n/** Time an availability check waits for a fresh noble to report its first state. */\nexport const THIRD_PARTY_BLE_STATE_SETTLE_TIMEOUT_MS = 3_000;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIO,IAAM,2BAA2B;AAAA,EACtC,MAAM;AAAA,EACN,UAAU;AAAA,EACV,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,OAAO;AAAA,EACP,WAAW;AAAA,EACX,aAAa;AAAA,EACb,cAAc;AAAA,EACd,WAAW;AAAA,EACX,UAAU;AAAA,EACV,eAAe;AAAA;AAAA,EAEf,cAAc;AAAA;AAAA,EAEd,cAAc;AAChB;AAMO,IAAM,mCAAmC;AAGzC,IAAM,oCAAoC;AAG1C,IAAM,gCAAgC;AAGtC,IAAM,sCAAsC;AAG5C,IAAM,0CAA0C;","names":[]}
|
package/dist/constants.mjs
CHANGED
|
@@ -3,13 +3,15 @@ import {
|
|
|
3
3
|
THIRD_PARTY_BLE_DEVICE_TTL_MS,
|
|
4
4
|
THIRD_PARTY_BLE_POWER_ON_TIMEOUT_MS,
|
|
5
5
|
THIRD_PARTY_BLE_SCAN_DURATION_MS,
|
|
6
|
-
THIRD_PARTY_BLE_SCAN_IDLE_STOP_MS
|
|
7
|
-
|
|
6
|
+
THIRD_PARTY_BLE_SCAN_IDLE_STOP_MS,
|
|
7
|
+
THIRD_PARTY_BLE_STATE_SETTLE_TIMEOUT_MS
|
|
8
|
+
} from "./chunk-ILABAQJY.mjs";
|
|
8
9
|
export {
|
|
9
10
|
THIRD_PARTY_BLE_CHANNELS,
|
|
10
11
|
THIRD_PARTY_BLE_DEVICE_TTL_MS,
|
|
11
12
|
THIRD_PARTY_BLE_POWER_ON_TIMEOUT_MS,
|
|
12
13
|
THIRD_PARTY_BLE_SCAN_DURATION_MS,
|
|
13
|
-
THIRD_PARTY_BLE_SCAN_IDLE_STOP_MS
|
|
14
|
+
THIRD_PARTY_BLE_SCAN_IDLE_STOP_MS,
|
|
15
|
+
THIRD_PARTY_BLE_STATE_SETTLE_TIMEOUT_MS
|
|
14
16
|
};
|
|
15
17
|
//# sourceMappingURL=constants.mjs.map
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ElectronBleConnectOptions, ElectronBleScanOptions } from '@onekeyfe/hwk-adapter-core';
|
|
2
2
|
export { THIRD_PARTY_BLE_CHANNELS, THIRD_PARTY_BLE_DEVICE_TTL_MS, THIRD_PARTY_BLE_POWER_ON_TIMEOUT_MS, THIRD_PARTY_BLE_SCAN_DURATION_MS, THIRD_PARTY_BLE_SCAN_IDLE_STOP_MS, ThirdPartyBleChannel } from './constants.mjs';
|
|
3
3
|
|
|
4
4
|
type BleDebugLogLevel = 'debug' | 'info' | 'warn' | 'error';
|
|
@@ -12,6 +12,26 @@ type BleDebugLogger = (entry: BleDebugLogEntry) => void;
|
|
|
12
12
|
/** Replace sensitive values at any depth; everything else is forwarded verbatim. */
|
|
13
13
|
declare function redactBleDebugLogData(data?: Record<string, unknown>): Record<string, unknown> | undefined;
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Main-process allowlist entry for one vendor key. The renderer only names the vendor; which
|
|
17
|
+
* peripherals it may see and which GATT profile and framing it may use are decided here, so an
|
|
18
|
+
* IPC caller cannot turn the service into a generic BLE proxy. UUID arguments may arrive in any
|
|
19
|
+
* case, with or without dashes.
|
|
20
|
+
*/
|
|
21
|
+
interface ThirdPartyBleVendorProfile {
|
|
22
|
+
/** Whether an advertised service UUID belongs to this vendor. */
|
|
23
|
+
isServiceUuid(uuid: string): boolean;
|
|
24
|
+
/** Whether a local name belongs to this vendor; the handler passes a length-capped name. */
|
|
25
|
+
isName?(name: string): boolean;
|
|
26
|
+
/** Whether this GATT profile and write framing is one the vendor's firmware uses. */
|
|
27
|
+
acceptsConnect(options: ElectronBleConnectOptions): boolean;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Vendors the desktop BLE service serves by default, keyed by the vendor string the connectors
|
|
31
|
+
* send. A host passing `vendors` replaces this map, so spread it to add a vendor.
|
|
32
|
+
*/
|
|
33
|
+
declare const DEFAULT_THIRD_PARTY_BLE_VENDORS: Readonly<Record<string, ThirdPartyBleVendorProfile>>;
|
|
34
|
+
|
|
15
35
|
/** Device info the main process returns to the renderer over IPC. */
|
|
16
36
|
interface ThirdPartyBleDeviceInfo {
|
|
17
37
|
/** Stable id (noble peripheral.id) used as connectId. */
|
|
@@ -77,7 +97,7 @@ interface ThirdPartyBleApi {
|
|
|
77
97
|
|
|
78
98
|
/**
|
|
79
99
|
* Subset of @stoprocent/noble we touch. We type as `any` to keep the package
|
|
80
|
-
* installable without the native module — it
|
|
100
|
+
* installable without the native module — the default factory loads it on first use.
|
|
81
101
|
*/
|
|
82
102
|
interface NobleLike {
|
|
83
103
|
state: string;
|
|
@@ -139,6 +159,11 @@ interface NobleBleHandlerOptions {
|
|
|
139
159
|
/** Override the overall connect timeout (tests only; defaults to 31s). */
|
|
140
160
|
connectTimeoutMs?: number;
|
|
141
161
|
logger?: BleDebugLogger;
|
|
162
|
+
/**
|
|
163
|
+
* Vendors served over IPC, keyed by the `vendor` the renderer sends. Replaces the default map
|
|
164
|
+
* (spread `DEFAULT_THIRD_PARTY_BLE_VENDORS` to add one); unknown vendors are rejected.
|
|
165
|
+
*/
|
|
166
|
+
vendors?: Record<string, ThirdPartyBleVendorProfile>;
|
|
142
167
|
}
|
|
143
168
|
/** Noble BLE logic decoupled from Electron IPC, so tests can use a fake noble. */
|
|
144
169
|
declare class NobleBleHandler {
|
|
@@ -146,6 +171,7 @@ declare class NobleBleHandler {
|
|
|
146
171
|
private readonly _factory;
|
|
147
172
|
private readonly _connectTimeoutMs;
|
|
148
173
|
private readonly _logger?;
|
|
174
|
+
private readonly _vendors;
|
|
149
175
|
private readonly _discovered;
|
|
150
176
|
private readonly _lastSeen;
|
|
151
177
|
private readonly _connected;
|
|
@@ -167,6 +193,7 @@ declare class NobleBleHandler {
|
|
|
167
193
|
private _nativeReleased;
|
|
168
194
|
private _lastNobleRecoverAt?;
|
|
169
195
|
constructor(options?: NobleBleHandlerOptions);
|
|
196
|
+
private _resolveVendor;
|
|
170
197
|
setNotificationListener(handler: (id: string, hexData: string) => void): void;
|
|
171
198
|
setDisconnectedListener(handler: (id: string) => void): void;
|
|
172
199
|
init(): Promise<void>;
|
|
@@ -242,6 +269,8 @@ declare class NobleBleHandler {
|
|
|
242
269
|
private _cleanupDevice;
|
|
243
270
|
private _requireEntry;
|
|
244
271
|
private _requireNoble;
|
|
272
|
+
/** A fresh noble reads `unknown` until its bindings report; wait for that first report. */
|
|
273
|
+
private _waitForKnownState;
|
|
245
274
|
private _waitForPoweredOn;
|
|
246
275
|
private _log;
|
|
247
276
|
}
|
|
@@ -274,4 +303,4 @@ interface ThirdPartyBleSupportHandle {
|
|
|
274
303
|
*/
|
|
275
304
|
declare function initThirdPartyBleSupport(webContents: WebContentsLike, options?: InitThirdPartyBleSupportOptions): ThirdPartyBleSupportHandle;
|
|
276
305
|
|
|
277
|
-
export { type BleDebugLogEntry, type BleDebugLogLevel, type BleDebugLogger, type InitThirdPartyBleSupportOptions, type IpcMainLike, NobleBleHandler, type NobleBleHandlerOptions, type ThirdPartyBleApi, type ThirdPartyBleAvailability, type ThirdPartyBleDeviceInfo, type ThirdPartyBleSupportHandle, initThirdPartyBleSupport, redactBleDebugLogData };
|
|
306
|
+
export { type BleDebugLogEntry, type BleDebugLogLevel, type BleDebugLogger, DEFAULT_THIRD_PARTY_BLE_VENDORS, type InitThirdPartyBleSupportOptions, type IpcMainLike, NobleBleHandler, type NobleBleHandlerOptions, type ThirdPartyBleApi, type ThirdPartyBleAvailability, type ThirdPartyBleDeviceInfo, type ThirdPartyBleSupportHandle, type ThirdPartyBleVendorProfile, initThirdPartyBleSupport, redactBleDebugLogData };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ElectronBleConnectOptions, ElectronBleScanOptions } from '@onekeyfe/hwk-adapter-core';
|
|
2
2
|
export { THIRD_PARTY_BLE_CHANNELS, THIRD_PARTY_BLE_DEVICE_TTL_MS, THIRD_PARTY_BLE_POWER_ON_TIMEOUT_MS, THIRD_PARTY_BLE_SCAN_DURATION_MS, THIRD_PARTY_BLE_SCAN_IDLE_STOP_MS, ThirdPartyBleChannel } from './constants.js';
|
|
3
3
|
|
|
4
4
|
type BleDebugLogLevel = 'debug' | 'info' | 'warn' | 'error';
|
|
@@ -12,6 +12,26 @@ type BleDebugLogger = (entry: BleDebugLogEntry) => void;
|
|
|
12
12
|
/** Replace sensitive values at any depth; everything else is forwarded verbatim. */
|
|
13
13
|
declare function redactBleDebugLogData(data?: Record<string, unknown>): Record<string, unknown> | undefined;
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* Main-process allowlist entry for one vendor key. The renderer only names the vendor; which
|
|
17
|
+
* peripherals it may see and which GATT profile and framing it may use are decided here, so an
|
|
18
|
+
* IPC caller cannot turn the service into a generic BLE proxy. UUID arguments may arrive in any
|
|
19
|
+
* case, with or without dashes.
|
|
20
|
+
*/
|
|
21
|
+
interface ThirdPartyBleVendorProfile {
|
|
22
|
+
/** Whether an advertised service UUID belongs to this vendor. */
|
|
23
|
+
isServiceUuid(uuid: string): boolean;
|
|
24
|
+
/** Whether a local name belongs to this vendor; the handler passes a length-capped name. */
|
|
25
|
+
isName?(name: string): boolean;
|
|
26
|
+
/** Whether this GATT profile and write framing is one the vendor's firmware uses. */
|
|
27
|
+
acceptsConnect(options: ElectronBleConnectOptions): boolean;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Vendors the desktop BLE service serves by default, keyed by the vendor string the connectors
|
|
31
|
+
* send. A host passing `vendors` replaces this map, so spread it to add a vendor.
|
|
32
|
+
*/
|
|
33
|
+
declare const DEFAULT_THIRD_PARTY_BLE_VENDORS: Readonly<Record<string, ThirdPartyBleVendorProfile>>;
|
|
34
|
+
|
|
15
35
|
/** Device info the main process returns to the renderer over IPC. */
|
|
16
36
|
interface ThirdPartyBleDeviceInfo {
|
|
17
37
|
/** Stable id (noble peripheral.id) used as connectId. */
|
|
@@ -77,7 +97,7 @@ interface ThirdPartyBleApi {
|
|
|
77
97
|
|
|
78
98
|
/**
|
|
79
99
|
* Subset of @stoprocent/noble we touch. We type as `any` to keep the package
|
|
80
|
-
* installable without the native module — it
|
|
100
|
+
* installable without the native module — the default factory loads it on first use.
|
|
81
101
|
*/
|
|
82
102
|
interface NobleLike {
|
|
83
103
|
state: string;
|
|
@@ -139,6 +159,11 @@ interface NobleBleHandlerOptions {
|
|
|
139
159
|
/** Override the overall connect timeout (tests only; defaults to 31s). */
|
|
140
160
|
connectTimeoutMs?: number;
|
|
141
161
|
logger?: BleDebugLogger;
|
|
162
|
+
/**
|
|
163
|
+
* Vendors served over IPC, keyed by the `vendor` the renderer sends. Replaces the default map
|
|
164
|
+
* (spread `DEFAULT_THIRD_PARTY_BLE_VENDORS` to add one); unknown vendors are rejected.
|
|
165
|
+
*/
|
|
166
|
+
vendors?: Record<string, ThirdPartyBleVendorProfile>;
|
|
142
167
|
}
|
|
143
168
|
/** Noble BLE logic decoupled from Electron IPC, so tests can use a fake noble. */
|
|
144
169
|
declare class NobleBleHandler {
|
|
@@ -146,6 +171,7 @@ declare class NobleBleHandler {
|
|
|
146
171
|
private readonly _factory;
|
|
147
172
|
private readonly _connectTimeoutMs;
|
|
148
173
|
private readonly _logger?;
|
|
174
|
+
private readonly _vendors;
|
|
149
175
|
private readonly _discovered;
|
|
150
176
|
private readonly _lastSeen;
|
|
151
177
|
private readonly _connected;
|
|
@@ -167,6 +193,7 @@ declare class NobleBleHandler {
|
|
|
167
193
|
private _nativeReleased;
|
|
168
194
|
private _lastNobleRecoverAt?;
|
|
169
195
|
constructor(options?: NobleBleHandlerOptions);
|
|
196
|
+
private _resolveVendor;
|
|
170
197
|
setNotificationListener(handler: (id: string, hexData: string) => void): void;
|
|
171
198
|
setDisconnectedListener(handler: (id: string) => void): void;
|
|
172
199
|
init(): Promise<void>;
|
|
@@ -242,6 +269,8 @@ declare class NobleBleHandler {
|
|
|
242
269
|
private _cleanupDevice;
|
|
243
270
|
private _requireEntry;
|
|
244
271
|
private _requireNoble;
|
|
272
|
+
/** A fresh noble reads `unknown` until its bindings report; wait for that first report. */
|
|
273
|
+
private _waitForKnownState;
|
|
245
274
|
private _waitForPoweredOn;
|
|
246
275
|
private _log;
|
|
247
276
|
}
|
|
@@ -274,4 +303,4 @@ interface ThirdPartyBleSupportHandle {
|
|
|
274
303
|
*/
|
|
275
304
|
declare function initThirdPartyBleSupport(webContents: WebContentsLike, options?: InitThirdPartyBleSupportOptions): ThirdPartyBleSupportHandle;
|
|
276
305
|
|
|
277
|
-
export { type BleDebugLogEntry, type BleDebugLogLevel, type BleDebugLogger, type InitThirdPartyBleSupportOptions, type IpcMainLike, NobleBleHandler, type NobleBleHandlerOptions, type ThirdPartyBleApi, type ThirdPartyBleAvailability, type ThirdPartyBleDeviceInfo, type ThirdPartyBleSupportHandle, initThirdPartyBleSupport, redactBleDebugLogData };
|
|
306
|
+
export { type BleDebugLogEntry, type BleDebugLogLevel, type BleDebugLogger, DEFAULT_THIRD_PARTY_BLE_VENDORS, type InitThirdPartyBleSupportOptions, type IpcMainLike, NobleBleHandler, type NobleBleHandlerOptions, type ThirdPartyBleApi, type ThirdPartyBleAvailability, type ThirdPartyBleDeviceInfo, type ThirdPartyBleSupportHandle, type ThirdPartyBleVendorProfile, initThirdPartyBleSupport, redactBleDebugLogData };
|
package/dist/index.js
CHANGED
|
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
+
DEFAULT_THIRD_PARTY_BLE_VENDORS: () => DEFAULT_THIRD_PARTY_BLE_VENDORS,
|
|
23
24
|
NobleBleHandler: () => NobleBleHandler,
|
|
24
25
|
THIRD_PARTY_BLE_CHANNELS: () => THIRD_PARTY_BLE_CHANNELS,
|
|
25
26
|
THIRD_PARTY_BLE_DEVICE_TTL_MS: () => THIRD_PARTY_BLE_DEVICE_TTL_MS,
|
|
@@ -113,25 +114,76 @@ var THIRD_PARTY_BLE_SCAN_DURATION_MS = 5e3;
|
|
|
113
114
|
var THIRD_PARTY_BLE_SCAN_IDLE_STOP_MS = 1e4;
|
|
114
115
|
var THIRD_PARTY_BLE_DEVICE_TTL_MS = 5e3;
|
|
115
116
|
var THIRD_PARTY_BLE_POWER_ON_TIMEOUT_MS = 1e4;
|
|
117
|
+
var THIRD_PARTY_BLE_STATE_SETTLE_TIMEOUT_MS = 3e3;
|
|
118
|
+
|
|
119
|
+
// src/vendorProfiles.ts
|
|
120
|
+
var normalizeBleUuid = (uuid) => uuid.replace(/-/g, "").toLowerCase();
|
|
121
|
+
var isUuidString = (value) => typeof value === "string";
|
|
122
|
+
var isIntegerInRange = (value, min, max) => typeof value === "number" && Number.isInteger(value) && value >= min && value <= max;
|
|
123
|
+
var TREZOR_SERVICE_UUID = normalizeBleUuid("8c000001-a59b-4d58-a9ad-073df69fa1b1");
|
|
124
|
+
var TREZOR_WRITE_UUID = normalizeBleUuid("8c000002-a59b-4d58-a9ad-073df69fa1b1");
|
|
125
|
+
var TREZOR_NOTIFY_UUID = normalizeBleUuid("8c000003-a59b-4d58-a9ad-073df69fa1b1");
|
|
126
|
+
var TREZOR_PACKET_SIZE = 244;
|
|
127
|
+
var TREZOR_MAX_CHUNK_DELAY_MS = 50;
|
|
128
|
+
var TREZOR_NAME_BRAND = /\bTrezor\b/i;
|
|
129
|
+
var TREZOR_NAME_MODEL = /\bSafe\s*7\b|\bT3W1\b/i;
|
|
130
|
+
var trezorProfile = {
|
|
131
|
+
isServiceUuid: (uuid) => isUuidString(uuid) && normalizeBleUuid(uuid) === TREZOR_SERVICE_UUID,
|
|
132
|
+
isName: (name) => TREZOR_NAME_BRAND.test(name) && TREZOR_NAME_MODEL.test(name),
|
|
133
|
+
acceptsConnect: (options) => {
|
|
134
|
+
const { write } = options;
|
|
135
|
+
return isUuidString(options.serviceUuid) && isUuidString(options.writeUuid) && isUuidString(options.notifyUuid) && normalizeBleUuid(options.serviceUuid) === TREZOR_SERVICE_UUID && normalizeBleUuid(options.writeUuid) === TREZOR_WRITE_UUID && normalizeBleUuid(options.notifyUuid) === TREZOR_NOTIFY_UUID && typeof write === "object" && write !== null && write.mode === "padded" && write.chunkSize === TREZOR_PACKET_SIZE && (write.chunkDelayMs === void 0 || isIntegerInRange(write.chunkDelayMs, 0, TREZOR_MAX_CHUNK_DELAY_MS)) && write.maxLength === void 0;
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
var LEDGER_UUID = /^13d634002c97([0-9a-f]{4})000([0-3])4c6564676572$/;
|
|
139
|
+
var LEDGER_ROLE_SERVICE = "0";
|
|
140
|
+
var LEDGER_ROLE_NOTIFY = "1";
|
|
141
|
+
var LEDGER_ROLE_WRITE = "2";
|
|
142
|
+
var LEDGER_ROLE_WRITE_CMD = "3";
|
|
143
|
+
var LEDGER_MAX_FRAME_SIZE = 255;
|
|
144
|
+
var parseLedgerUuid = (uuid) => {
|
|
145
|
+
if (!isUuidString(uuid)) return void 0;
|
|
146
|
+
const parsed = LEDGER_UUID.exec(normalizeBleUuid(uuid));
|
|
147
|
+
return parsed ? { model: parsed[1], role: parsed[2] } : void 0;
|
|
148
|
+
};
|
|
149
|
+
var ledgerProfile = {
|
|
150
|
+
isServiceUuid: (uuid) => parseLedgerUuid(uuid)?.role === LEDGER_ROLE_SERVICE,
|
|
151
|
+
acceptsConnect: (options) => {
|
|
152
|
+
const service = parseLedgerUuid(options.serviceUuid);
|
|
153
|
+
const notify = parseLedgerUuid(options.notifyUuid);
|
|
154
|
+
const write = parseLedgerUuid(options.writeUuid);
|
|
155
|
+
const framing = options.write;
|
|
156
|
+
return service?.role === LEDGER_ROLE_SERVICE && notify?.role === LEDGER_ROLE_NOTIFY && (write?.role === LEDGER_ROLE_WRITE || write?.role === LEDGER_ROLE_WRITE_CMD) && notify.model === service.model && write.model === service.model && typeof framing === "object" && framing !== null && framing.mode === "raw" && isIntegerInRange(framing.maxLength, 1, LEDGER_MAX_FRAME_SIZE) && framing.chunkSize === void 0 && framing.chunkDelayMs === void 0;
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
var DEFAULT_THIRD_PARTY_BLE_VENDORS = Object.freeze({
|
|
160
|
+
ledger: ledgerProfile,
|
|
161
|
+
trezor: trezorProfile
|
|
162
|
+
});
|
|
116
163
|
|
|
117
164
|
// src/NobleBleHandler.ts
|
|
118
165
|
var DEFAULT_NOBLE_FACTORY = () => {
|
|
119
166
|
const noble = require("@stoprocent/noble");
|
|
120
167
|
return noble;
|
|
121
168
|
};
|
|
122
|
-
var
|
|
123
|
-
var matchesPeripheral = (p,
|
|
124
|
-
if (!match) return false;
|
|
169
|
+
var BLE_NAME_MATCH_MAX_LENGTH = 64;
|
|
170
|
+
var matchesPeripheral = (p, profile, narrowTo) => {
|
|
125
171
|
const adv = p.advertisement ?? {};
|
|
126
172
|
const advertised = adv.serviceUuids ?? [];
|
|
127
|
-
if (
|
|
128
|
-
(uuid) =>
|
|
173
|
+
if (advertised.some(
|
|
174
|
+
(uuid) => typeof uuid === "string" && profile.isServiceUuid(uuid) && (!narrowTo || narrowTo.has(normalizeBleUuid(uuid)))
|
|
129
175
|
)) {
|
|
130
176
|
return true;
|
|
131
177
|
}
|
|
132
178
|
const name = adv.localName;
|
|
133
|
-
if (!
|
|
134
|
-
return
|
|
179
|
+
if (!profile.isName || typeof name !== "string" || !name) return false;
|
|
180
|
+
return profile.isName(name.slice(0, BLE_NAME_MATCH_MAX_LENGTH));
|
|
181
|
+
};
|
|
182
|
+
var requestedServiceUuids = (options) => {
|
|
183
|
+
const requested = options?.match ? options.match.serviceUuids : options?.serviceUuids;
|
|
184
|
+
if (!Array.isArray(requested)) return void 0;
|
|
185
|
+
const uuids = requested.filter((uuid) => typeof uuid === "string");
|
|
186
|
+
return uuids.length ? new Set(uuids.map(normalizeBleUuid)) : void 0;
|
|
135
187
|
};
|
|
136
188
|
var peripheralToInfo = (p) => {
|
|
137
189
|
const adv = p.advertisement ?? {};
|
|
@@ -193,6 +245,12 @@ var NobleBleHandler = class {
|
|
|
193
245
|
this._factory = options.nobleFactory ?? DEFAULT_NOBLE_FACTORY;
|
|
194
246
|
this._connectTimeoutMs = options.connectTimeoutMs ?? BLE_CONNECT_TIMEOUT_MS;
|
|
195
247
|
this._logger = options.logger;
|
|
248
|
+
this._vendors = new Map(Object.entries(options.vendors ?? DEFAULT_THIRD_PARTY_BLE_VENDORS));
|
|
249
|
+
}
|
|
250
|
+
_resolveVendor(vendor) {
|
|
251
|
+
const profile = typeof vendor === "string" ? this._vendors.get(vendor) : void 0;
|
|
252
|
+
if (typeof vendor !== "string" || !profile) throw new Error("Unsupported BLE vendor");
|
|
253
|
+
return { vendor, profile };
|
|
196
254
|
}
|
|
197
255
|
setNotificationListener(handler) {
|
|
198
256
|
this._onNotification = handler;
|
|
@@ -233,6 +291,8 @@ var NobleBleHandler = class {
|
|
|
233
291
|
return { available: false, state: "unsupported", initialized: false };
|
|
234
292
|
}
|
|
235
293
|
}
|
|
294
|
+
await this._waitForKnownState(THIRD_PARTY_BLE_STATE_SETTLE_TIMEOUT_MS);
|
|
295
|
+
this._assertActive();
|
|
236
296
|
const state = this._noble?.state ?? "unknown";
|
|
237
297
|
return {
|
|
238
298
|
available: state === "poweredOn",
|
|
@@ -245,14 +305,15 @@ var NobleBleHandler = class {
|
|
|
245
305
|
* packet, and a Safe 7 ADV carries only its name (UUID is in the scan response).
|
|
246
306
|
*/
|
|
247
307
|
async scan(options) {
|
|
248
|
-
this.
|
|
308
|
+
const { vendor, profile } = this._resolveVendor(options?.vendor);
|
|
309
|
+
this._scanOwners.add(vendor);
|
|
249
310
|
try {
|
|
250
311
|
await this.init();
|
|
251
312
|
} catch (error) {
|
|
252
|
-
this._scanOwners.delete(
|
|
313
|
+
this._scanOwners.delete(vendor);
|
|
253
314
|
throw error;
|
|
254
315
|
}
|
|
255
|
-
if (!this._scanOwners.has(
|
|
316
|
+
if (!this._scanOwners.has(vendor)) return [];
|
|
256
317
|
try {
|
|
257
318
|
await this._setScanning(true);
|
|
258
319
|
} catch (error) {
|
|
@@ -261,7 +322,7 @@ var NobleBleHandler = class {
|
|
|
261
322
|
}
|
|
262
323
|
this._assertActive();
|
|
263
324
|
this._armIdleStop();
|
|
264
|
-
const devices = this._snapshot(options);
|
|
325
|
+
const devices = this._snapshot(vendor, profile, requestedServiceUuids(options));
|
|
265
326
|
if (devices.length === 0) {
|
|
266
327
|
this._log("warn", "scan.empty", {
|
|
267
328
|
raw: this._discovered.size,
|
|
@@ -275,9 +336,8 @@ var NobleBleHandler = class {
|
|
|
275
336
|
* In-range devices matching the caller, minus TTL-expired ones. `_discovered`
|
|
276
337
|
* is only a cache; a missing device can still be reached by `_directConnect`.
|
|
277
338
|
*/
|
|
278
|
-
_snapshot(
|
|
339
|
+
_snapshot(vendor, profile, narrowTo) {
|
|
279
340
|
const now = Date.now();
|
|
280
|
-
const match = options?.match ?? { serviceUuids: options?.serviceUuids };
|
|
281
341
|
const result = [];
|
|
282
342
|
for (const [id, peripheral] of this._discovered) {
|
|
283
343
|
if (now - (this._lastSeen.get(id) ?? 0) > THIRD_PARTY_BLE_DEVICE_TTL_MS) {
|
|
@@ -285,11 +345,11 @@ var NobleBleHandler = class {
|
|
|
285
345
|
this._lastSeen.delete(id);
|
|
286
346
|
continue;
|
|
287
347
|
}
|
|
288
|
-
if (!matchesPeripheral(peripheral,
|
|
348
|
+
if (!matchesPeripheral(peripheral, profile, narrowTo)) continue;
|
|
289
349
|
result.push(peripheralToInfo(peripheral));
|
|
290
350
|
}
|
|
291
351
|
for (const [id, entry] of this._connected) {
|
|
292
|
-
if (entry.vendor !==
|
|
352
|
+
if (entry.vendor !== vendor) continue;
|
|
293
353
|
if (result.some((info) => info.id === id)) continue;
|
|
294
354
|
result.push(peripheralToInfo(entry.peripheral));
|
|
295
355
|
}
|
|
@@ -406,7 +466,9 @@ var NobleBleHandler = class {
|
|
|
406
466
|
*/
|
|
407
467
|
getDevice(id) {
|
|
408
468
|
const p = this._discovered.get(id);
|
|
409
|
-
if (!p)
|
|
469
|
+
if (!p || ![...this._vendors.values()].some((profile) => matchesPeripheral(p, profile))) {
|
|
470
|
+
return null;
|
|
471
|
+
}
|
|
410
472
|
return peripheralToInfo(p);
|
|
411
473
|
}
|
|
412
474
|
/** Live RSSI (dBm) of a connected peripheral, else the cached scan-time value. */
|
|
@@ -523,10 +585,13 @@ var NobleBleHandler = class {
|
|
|
523
585
|
// `timed out` (unreachable) and `connection failed` (stale bond) differently.
|
|
524
586
|
async connect(id, options) {
|
|
525
587
|
if (!options || !options.vendor || ![options.serviceUuid, options.writeUuid, options.notifyUuid].every(
|
|
526
|
-
(uuid) => typeof uuid === "string" && /^[0-9a-f]{32}$/i.test(
|
|
588
|
+
(uuid) => typeof uuid === "string" && /^[0-9a-f]{32}$/i.test(normalizeBleUuid(uuid))
|
|
527
589
|
)) {
|
|
528
590
|
throw new Error("Invalid BLE GATT profile");
|
|
529
591
|
}
|
|
592
|
+
if (!this._resolveVendor(options.vendor).profile.acceptsConnect(options)) {
|
|
593
|
+
throw new Error(`BLE GATT profile not allowed for ${options.vendor}`);
|
|
594
|
+
}
|
|
530
595
|
this._assertActive();
|
|
531
596
|
const claim = { abandoned: false };
|
|
532
597
|
let abandon;
|
|
@@ -563,9 +628,9 @@ var NobleBleHandler = class {
|
|
|
563
628
|
})();
|
|
564
629
|
attempt.settled = Promise.allSettled([nativeOperation, caller]).finally(() => {
|
|
565
630
|
this._connectAttempts.delete(attempt);
|
|
631
|
+
if (this._scanOwners.size > 0) this._armIdleStop();
|
|
566
632
|
const connectScanWaiting = [...this._scanOwners].some((owner) => typeof owner === "symbol");
|
|
567
633
|
if (connectScanWaiting) {
|
|
568
|
-
this._armIdleStop();
|
|
569
634
|
void this._setScanning(true).catch(() => void 0);
|
|
570
635
|
}
|
|
571
636
|
});
|
|
@@ -634,10 +699,10 @@ var NobleBleHandler = class {
|
|
|
634
699
|
[options.serviceUuid],
|
|
635
700
|
[options.writeUuid, options.notifyUuid]
|
|
636
701
|
);
|
|
637
|
-
const writeUuid =
|
|
638
|
-
const notifyUuid =
|
|
639
|
-
const writeChar = characteristics.find((c) =>
|
|
640
|
-
const notifyChar = characteristics.find((c) =>
|
|
702
|
+
const writeUuid = normalizeBleUuid(options.writeUuid);
|
|
703
|
+
const notifyUuid = normalizeBleUuid(options.notifyUuid);
|
|
704
|
+
const writeChar = characteristics.find((c) => normalizeBleUuid(c.uuid) === writeUuid);
|
|
705
|
+
const notifyChar = characteristics.find((c) => normalizeBleUuid(c.uuid) === notifyUuid);
|
|
641
706
|
if (!writeChar || !notifyChar) {
|
|
642
707
|
throw new Error(`BLE characteristics not found on device ${id}`);
|
|
643
708
|
}
|
|
@@ -839,6 +904,22 @@ var NobleBleHandler = class {
|
|
|
839
904
|
if (!this._noble) throw new Error("Desktop BLE: noble was not initialized");
|
|
840
905
|
return this._noble;
|
|
841
906
|
}
|
|
907
|
+
/** A fresh noble reads `unknown` until its bindings report; wait for that first report. */
|
|
908
|
+
async _waitForKnownState(timeoutMs) {
|
|
909
|
+
const noble = this._requireNoble();
|
|
910
|
+
if (noble.state !== "unknown") return;
|
|
911
|
+
await new Promise((resolve) => {
|
|
912
|
+
const settle = () => {
|
|
913
|
+
clearTimeout(timer);
|
|
914
|
+
noble.removeListener("stateChange", settle);
|
|
915
|
+
this._pendingCancellations.delete(settle);
|
|
916
|
+
resolve();
|
|
917
|
+
};
|
|
918
|
+
const timer = setTimeout(settle, timeoutMs);
|
|
919
|
+
this._pendingCancellations.add(settle);
|
|
920
|
+
noble.on("stateChange", settle);
|
|
921
|
+
});
|
|
922
|
+
}
|
|
842
923
|
async _waitForPoweredOn(timeoutMs) {
|
|
843
924
|
const noble = this._requireNoble();
|
|
844
925
|
if (noble.state === "poweredOn") return;
|
|
@@ -948,6 +1029,7 @@ function initThirdPartyBleSupport(webContents, options = {}) {
|
|
|
948
1029
|
}
|
|
949
1030
|
// Annotate the CommonJS export names for ESM import in node:
|
|
950
1031
|
0 && (module.exports = {
|
|
1032
|
+
DEFAULT_THIRD_PARTY_BLE_VENDORS,
|
|
951
1033
|
NobleBleHandler,
|
|
952
1034
|
THIRD_PARTY_BLE_CHANNELS,
|
|
953
1035
|
THIRD_PARTY_BLE_DEVICE_TTL_MS,
|