@onekeyfe/hd-transport-web-device 1.0.38-alpha.2 → 1.0.39-alpha.10
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/electron-ble-transport.d.ts +1 -0
- package/dist/electron-ble-transport.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +46 -5
- package/package.json +4 -4
- package/src/electron-ble-transport.ts +52 -3
- package/dist/webble-utils.d.ts +0 -4
- package/dist/webble-utils.d.ts.map +0 -1
- package/src/webble-utils.ts +0 -30
|
@@ -23,6 +23,7 @@ export default class ElectronBleTransport {
|
|
|
23
23
|
private dataBuffers;
|
|
24
24
|
private notificationCleanups;
|
|
25
25
|
private disconnectCleanups;
|
|
26
|
+
private handleBluetoothError;
|
|
26
27
|
private cleanupDeviceState;
|
|
27
28
|
init(logger: any, emitter?: EventEmitter): void;
|
|
28
29
|
configure(signedData: any): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"electron-ble-transport.d.ts","sourceRoot":"","sources":["../src/electron-ble-transport.ts"],"names":[],"mappings":";AAAA,OAAO,SAAkD,MAAM,wBAAwB,CAAC;AACxF,OAAO,
|
|
1
|
+
{"version":3,"file":"electron-ble-transport.d.ts","sourceRoot":"","sources":["../src/electron-ble-transport.ts"],"names":[],"mappings":";AAAA,OAAO,SAAkD,MAAM,wBAAwB,CAAC;AACxF,OAAO,EAIL,QAAQ,EAGT,MAAM,qBAAqB,CAAC;AAE7B,OAAO,KAAK,YAAY,MAAM,QAAQ,CAAC;AAEvC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAKlE,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd,UAAU,CAAC,EAAE,UAAU,CAAC;KACzB;CACF;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC,CAAC;AASF,MAAM,CAAC,OAAO,OAAO,oBAAoB;IACvC,SAAS,EAAE,UAAU,CAAC,OAAO,SAAS,CAAC,cAAc,CAAC,GAAG,SAAS,CAAC;IAEnE,IAAI,SAA0B;IAE9B,UAAU,UAAS;IAEnB,UAAU,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAI,CAAQ;IAExC,GAAG,CAAC,EAAE,GAAG,CAAC;IAEV,OAAO,CAAC,EAAE,YAAY,CAAC;IAGvB,OAAO,CAAC,gBAAgB,CAA0B;IAGlD,OAAO,CAAC,WAAW,CAAsE;IAGzF,OAAO,CAAC,oBAAoB,CAAsC;IAGlE,OAAO,CAAC,kBAAkB,CAAsC;IAGhE,OAAO,CAAC,oBAAoB;IAmC5B,OAAO,CAAC,kBAAkB;IAmB1B,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,YAAY;IAexC,SAAS,CAAC,UAAU,EAAE,GAAG;IAMzB,MAAM;IAEA,SAAS,IAAI,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAcpD,OAAO,CAAC,KAAK,EAAE,eAAe;;;;IA8E9B,OAAO,CAAC,EAAE,EAAE,MAAM;IAwBxB,OAAO,CAAC,sBAAsB;IA2BxB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IA2EpE,OAAO,CAAC,yBAAyB;CAyDlC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -54,6 +54,7 @@ declare class ElectronBleTransport {
|
|
|
54
54
|
private dataBuffers;
|
|
55
55
|
private notificationCleanups;
|
|
56
56
|
private disconnectCleanups;
|
|
57
|
+
private handleBluetoothError;
|
|
57
58
|
private cleanupDeviceState;
|
|
58
59
|
init(logger: any, emitter?: EventEmitter): void;
|
|
59
60
|
configure(signedData: any): void;
|
package/dist/index.js
CHANGED
|
@@ -269,6 +269,35 @@ class ElectronBleTransport {
|
|
|
269
269
|
this.notificationCleanups = new Map();
|
|
270
270
|
this.disconnectCleanups = new Map();
|
|
271
271
|
}
|
|
272
|
+
handleBluetoothError(error) {
|
|
273
|
+
if (error && typeof error === 'object') {
|
|
274
|
+
if ('code' in error) {
|
|
275
|
+
if (error.code === hdShared.HardwareErrorCode.BlePoweredOff) {
|
|
276
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BlePoweredOff);
|
|
277
|
+
}
|
|
278
|
+
if (error.code === hdShared.HardwareErrorCode.BleUnsupported) {
|
|
279
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleUnsupported);
|
|
280
|
+
}
|
|
281
|
+
if (error.code === hdShared.HardwareErrorCode.BlePermissionError) {
|
|
282
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BlePermissionError);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
const errorMessage = error.message || String(error);
|
|
286
|
+
const poweredOffMessage = hdShared.HardwareErrorCodeMessage[hdShared.HardwareErrorCode.BlePoweredOff];
|
|
287
|
+
const unsupportedMessage = hdShared.HardwareErrorCodeMessage[hdShared.HardwareErrorCode.BleUnsupported];
|
|
288
|
+
const permissionMessage = hdShared.HardwareErrorCodeMessage[hdShared.HardwareErrorCode.BlePermissionError];
|
|
289
|
+
if (errorMessage.includes(poweredOffMessage) || errorMessage.includes('poweredOff')) {
|
|
290
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BlePoweredOff);
|
|
291
|
+
}
|
|
292
|
+
if (errorMessage.includes(unsupportedMessage) || errorMessage.includes('unsupported')) {
|
|
293
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleUnsupported);
|
|
294
|
+
}
|
|
295
|
+
if (errorMessage.includes(permissionMessage) || errorMessage.includes('unauthorized')) {
|
|
296
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BlePermissionError);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
throw error;
|
|
300
|
+
}
|
|
272
301
|
cleanupDeviceState(deviceId) {
|
|
273
302
|
this.connectedDevices.delete(deviceId);
|
|
274
303
|
this.dataBuffers.delete(deviceId);
|
|
@@ -310,7 +339,7 @@ class ElectronBleTransport {
|
|
|
310
339
|
}
|
|
311
340
|
catch (error) {
|
|
312
341
|
(_b = this.Log) === null || _b === void 0 ? void 0 : _b.error('[Transport] Noble BLE enumerate failed:', error);
|
|
313
|
-
|
|
342
|
+
this.handleBluetoothError(error);
|
|
314
343
|
}
|
|
315
344
|
});
|
|
316
345
|
}
|
|
@@ -332,8 +361,13 @@ class ElectronBleTransport {
|
|
|
332
361
|
if (!device) {
|
|
333
362
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceNotFound, `Device ${uuid} not found`);
|
|
334
363
|
}
|
|
335
|
-
|
|
336
|
-
|
|
364
|
+
try {
|
|
365
|
+
yield window.desktopApi.nobleBle.connect(uuid);
|
|
366
|
+
this.connectedDevices.add(uuid);
|
|
367
|
+
}
|
|
368
|
+
catch (error) {
|
|
369
|
+
this.handleBluetoothError(error);
|
|
370
|
+
}
|
|
337
371
|
this.dataBuffers.set(uuid, { buffer: [], bufferLength: 0 });
|
|
338
372
|
yield window.desktopApi.nobleBle.subscribe(uuid);
|
|
339
373
|
const cleanup = window.desktopApi.nobleBle.onNotification((deviceId, data) => {
|
|
@@ -388,10 +422,17 @@ class ElectronBleTransport {
|
|
|
388
422
|
});
|
|
389
423
|
}
|
|
390
424
|
handleNotificationData(deviceId, hexData) {
|
|
391
|
-
var _a;
|
|
425
|
+
var _a, _b;
|
|
426
|
+
if (hexData === 'PAIRING_REJECTED') {
|
|
427
|
+
(_a = this.Log) === null || _a === void 0 ? void 0 : _a.debug('[Transport] Pairing rejection detected for device:', deviceId);
|
|
428
|
+
if (this.runPromise) {
|
|
429
|
+
this.runPromise.reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleDeviceBondedCanceled));
|
|
430
|
+
}
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
392
433
|
const result = this.processNotificationPacket(deviceId, hexData);
|
|
393
434
|
if (result.error) {
|
|
394
|
-
(
|
|
435
|
+
(_b = this.Log) === null || _b === void 0 ? void 0 : _b.error('[Transport] Packet processing error:', result.error);
|
|
395
436
|
if (this.runPromise) {
|
|
396
437
|
this.runPromise.reject(hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleWriteCharacteristicError));
|
|
397
438
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onekeyfe/hd-transport-web-device",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.39-alpha.10",
|
|
4
4
|
"author": "OneKey",
|
|
5
5
|
"homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
|
|
6
6
|
"license": "MIT",
|
|
@@ -20,12 +20,12 @@
|
|
|
20
20
|
"lint:fix": "eslint . --fix"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@onekeyfe/hd-shared": "^1.0.
|
|
24
|
-
"@onekeyfe/hd-transport": "^1.0.
|
|
23
|
+
"@onekeyfe/hd-shared": "^1.0.39-alpha.10",
|
|
24
|
+
"@onekeyfe/hd-transport": "^1.0.39-alpha.10"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@types/w3c-web-usb": "^1.0.6",
|
|
28
28
|
"@types/web-bluetooth": "^0.0.17"
|
|
29
29
|
},
|
|
30
|
-
"gitHead": "
|
|
30
|
+
"gitHead": "97fbf97e4ba3388fdc01be8722a94358715dcf12"
|
|
31
31
|
}
|
|
@@ -2,6 +2,7 @@ import transport, { COMMON_HEADER_SIZE, LogBlockCommand } from '@onekeyfe/hd-tra
|
|
|
2
2
|
import {
|
|
3
3
|
ERRORS,
|
|
4
4
|
HardwareErrorCode,
|
|
5
|
+
HardwareErrorCodeMessage,
|
|
5
6
|
Deferred,
|
|
6
7
|
createDeferred,
|
|
7
8
|
isHeaderChunk,
|
|
@@ -57,6 +58,41 @@ export default class ElectronBleTransport {
|
|
|
57
58
|
// Disconnect listener cleanup functions
|
|
58
59
|
private disconnectCleanups: Map<string, () => void> = new Map();
|
|
59
60
|
|
|
61
|
+
// Handle bluetooth related errors with proper error code mapping
|
|
62
|
+
private handleBluetoothError(error: any): never {
|
|
63
|
+
if (error && typeof error === 'object') {
|
|
64
|
+
// Check for specific bluetooth error codes
|
|
65
|
+
if ('code' in error) {
|
|
66
|
+
if (error.code === HardwareErrorCode.BlePoweredOff) {
|
|
67
|
+
throw ERRORS.TypedError(HardwareErrorCode.BlePoweredOff);
|
|
68
|
+
}
|
|
69
|
+
if (error.code === HardwareErrorCode.BleUnsupported) {
|
|
70
|
+
throw ERRORS.TypedError(HardwareErrorCode.BleUnsupported);
|
|
71
|
+
}
|
|
72
|
+
if (error.code === HardwareErrorCode.BlePermissionError) {
|
|
73
|
+
throw ERRORS.TypedError(HardwareErrorCode.BlePermissionError);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// Check for error message containing bluetooth state related text using predefined messages
|
|
77
|
+
const errorMessage = error.message || String(error);
|
|
78
|
+
const poweredOffMessage = HardwareErrorCodeMessage[HardwareErrorCode.BlePoweredOff];
|
|
79
|
+
const unsupportedMessage = HardwareErrorCodeMessage[HardwareErrorCode.BleUnsupported];
|
|
80
|
+
const permissionMessage = HardwareErrorCodeMessage[HardwareErrorCode.BlePermissionError];
|
|
81
|
+
|
|
82
|
+
if (errorMessage.includes(poweredOffMessage) || errorMessage.includes('poweredOff')) {
|
|
83
|
+
throw ERRORS.TypedError(HardwareErrorCode.BlePoweredOff);
|
|
84
|
+
}
|
|
85
|
+
if (errorMessage.includes(unsupportedMessage) || errorMessage.includes('unsupported')) {
|
|
86
|
+
throw ERRORS.TypedError(HardwareErrorCode.BleUnsupported);
|
|
87
|
+
}
|
|
88
|
+
if (errorMessage.includes(permissionMessage) || errorMessage.includes('unauthorized')) {
|
|
89
|
+
throw ERRORS.TypedError(HardwareErrorCode.BlePermissionError);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
throw error;
|
|
94
|
+
}
|
|
95
|
+
|
|
60
96
|
// Clean up all device state and listeners - unified cleanup function
|
|
61
97
|
private cleanupDeviceState(deviceId: string): void {
|
|
62
98
|
this.connectedDevices.delete(deviceId);
|
|
@@ -110,7 +146,7 @@ export default class ElectronBleTransport {
|
|
|
110
146
|
return devices;
|
|
111
147
|
} catch (error) {
|
|
112
148
|
this.Log?.error('[Transport] Noble BLE enumerate failed:', error);
|
|
113
|
-
|
|
149
|
+
this.handleBluetoothError(error);
|
|
114
150
|
}
|
|
115
151
|
}
|
|
116
152
|
|
|
@@ -138,8 +174,12 @@ export default class ElectronBleTransport {
|
|
|
138
174
|
}
|
|
139
175
|
|
|
140
176
|
// Connect to device
|
|
141
|
-
|
|
142
|
-
|
|
177
|
+
try {
|
|
178
|
+
await window.desktopApi.nobleBle.connect(uuid);
|
|
179
|
+
this.connectedDevices.add(uuid);
|
|
180
|
+
} catch (error) {
|
|
181
|
+
this.handleBluetoothError(error);
|
|
182
|
+
}
|
|
143
183
|
|
|
144
184
|
// Initialize data buffer for this device
|
|
145
185
|
this.dataBuffers.set(uuid, { buffer: [], bufferLength: 0 });
|
|
@@ -213,6 +253,15 @@ export default class ElectronBleTransport {
|
|
|
213
253
|
|
|
214
254
|
// Handle notification data from Noble BLE
|
|
215
255
|
private handleNotificationData(deviceId: string, hexData: string): void {
|
|
256
|
+
// Check for pairing rejection
|
|
257
|
+
if (hexData === 'PAIRING_REJECTED') {
|
|
258
|
+
this.Log?.debug('[Transport] Pairing rejection detected for device:', deviceId);
|
|
259
|
+
if (this.runPromise) {
|
|
260
|
+
this.runPromise.reject(ERRORS.TypedError(HardwareErrorCode.BleDeviceBondedCanceled));
|
|
261
|
+
}
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
|
|
216
265
|
const result = this.processNotificationPacket(deviceId, hexData);
|
|
217
266
|
|
|
218
267
|
if (result.error) {
|
package/dist/webble-utils.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"webble-utils.d.ts","sourceRoot":"","sources":["../src/webble-utils.ts"],"names":[],"mappings":";AAEA,eAAO,MAAM,aAAa,UAAW,MAAM,GAAG,UAAU,KAAG,OAa1D,CAAC;AAEF,eAAO,MAAM,cAAc,SAAU,MAAM,GAAG,IAAI,OAAO,MAAM,KAAG,OAYjE,CAAC"}
|
package/src/webble-utils.ts
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { MESSAGE_TOP_CHAR, MESSAGE_HEADER_BYTE } from '@onekeyfe/hd-transport';
|
|
2
|
-
|
|
3
|
-
export const isHeaderChunk = (chunk: Buffer | Uint8Array): boolean => {
|
|
4
|
-
if (chunk.length < 9) return false;
|
|
5
|
-
const [MagicQuestionMark, sharp1, sharp2] = chunk;
|
|
6
|
-
|
|
7
|
-
if (
|
|
8
|
-
String.fromCharCode(MagicQuestionMark) === String.fromCharCode(MESSAGE_TOP_CHAR) &&
|
|
9
|
-
String.fromCharCode(sharp1) === String.fromCharCode(MESSAGE_HEADER_BYTE) &&
|
|
10
|
-
String.fromCharCode(sharp2) === String.fromCharCode(MESSAGE_HEADER_BYTE)
|
|
11
|
-
) {
|
|
12
|
-
return true;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
return false;
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
export const isOnekeyDevice = (name: string | null, id?: string): boolean => {
|
|
19
|
-
if (id?.startsWith?.('MI')) {
|
|
20
|
-
return true;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
// 过滤 BixinKeyxxx 和 Kxxxx 和 Txxxx
|
|
24
|
-
// i 忽略大小写模式
|
|
25
|
-
const re = /(BixinKey\d{10})|(K\d{4})|(T\d{4})|(Touch\s\w{4})|(Pro\s\w{4})/i;
|
|
26
|
-
if (name && re.exec(name)) {
|
|
27
|
-
return true;
|
|
28
|
-
}
|
|
29
|
-
return false;
|
|
30
|
-
};
|