@onekeyfe/hd-transport-web-device 1.2.0-alpha.23 → 1.2.0-alpha.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import transport, { PROTOCOL_V2_CHANNEL_BLE_UART, bytesToHex } from '@onekeyfe/hd-transport';
|
|
2
2
|
import { HardwareErrorCode } from '@onekeyfe/hd-shared';
|
|
3
|
+
import EventEmitter from 'events';
|
|
3
4
|
|
|
4
5
|
import ElectronBleTransport from '../src/electron-ble-transport';
|
|
5
6
|
|
|
@@ -111,7 +112,10 @@ const createNobleBle = (device = { id: 'flaky-pro2-id', name: 'Unknown BLE Devic
|
|
|
111
112
|
),
|
|
112
113
|
});
|
|
113
114
|
|
|
114
|
-
const configureTransport = (
|
|
115
|
+
const configureTransport = (
|
|
116
|
+
nobleBle: ReturnType<typeof createNobleBle>,
|
|
117
|
+
emitter?: EventEmitter
|
|
118
|
+
) => {
|
|
115
119
|
(global as any).window = {
|
|
116
120
|
desktopApi: {
|
|
117
121
|
nobleBle,
|
|
@@ -119,7 +123,7 @@ const configureTransport = (nobleBle: ReturnType<typeof createNobleBle>) => {
|
|
|
119
123
|
};
|
|
120
124
|
|
|
121
125
|
const transport = new ElectronBleTransport();
|
|
122
|
-
transport.init(createLogger());
|
|
126
|
+
transport.init(createLogger(), emitter);
|
|
123
127
|
transport.configure(protocolV1Schema);
|
|
124
128
|
transport.configureProtocolV2(protocolV2Schema);
|
|
125
129
|
return transport;
|
|
@@ -131,6 +135,54 @@ describe('ElectronBleTransport protocol detection', () => {
|
|
|
131
135
|
jest.clearAllMocks();
|
|
132
136
|
});
|
|
133
137
|
|
|
138
|
+
test('keeps raw BLE lifecycle payloads off the public device event channel', async () => {
|
|
139
|
+
const device = { id: 'lifecycle-pro2-id', name: 'OneKey Pro 2' };
|
|
140
|
+
const nobleBle = createNobleBle(device);
|
|
141
|
+
const emitter = new EventEmitter();
|
|
142
|
+
let notificationHandler: ((deviceId: string, data: string) => void) | undefined;
|
|
143
|
+
let disconnectHandler: ((device: { id: string; name: string | null }) => void) | undefined;
|
|
144
|
+
let responseSeq = 0;
|
|
145
|
+
|
|
146
|
+
nobleBle.onNotification.mockImplementation(handler => {
|
|
147
|
+
notificationHandler = handler;
|
|
148
|
+
return jest.fn();
|
|
149
|
+
});
|
|
150
|
+
nobleBle.onDeviceDisconnected.mockImplementation(handler => {
|
|
151
|
+
disconnectHandler = handler;
|
|
152
|
+
return jest.fn();
|
|
153
|
+
});
|
|
154
|
+
nobleBle.write.mockImplementation(() => {
|
|
155
|
+
responseSeq += 1;
|
|
156
|
+
const response = ProtocolV2.encodeFrame(
|
|
157
|
+
schemas,
|
|
158
|
+
'Success',
|
|
159
|
+
{ message: 'ok' },
|
|
160
|
+
{ router: PROTOCOL_V2_CHANNEL_BLE_UART, seq: responseSeq }
|
|
161
|
+
);
|
|
162
|
+
setTimeout(() => notificationHandler?.(device.id, bytesToHex(response)), 0);
|
|
163
|
+
return Promise.resolve();
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
const publicConnect = jest.fn();
|
|
167
|
+
const publicDisconnect = jest.fn();
|
|
168
|
+
const transportDisconnect = jest.fn();
|
|
169
|
+
emitter.on('device-connect', publicConnect);
|
|
170
|
+
emitter.on('device-disconnect', publicDisconnect);
|
|
171
|
+
emitter.on('transport-device-disconnect', transportDisconnect);
|
|
172
|
+
const bleTransport = configureTransport(nobleBle, emitter);
|
|
173
|
+
|
|
174
|
+
await bleTransport.acquire({ uuid: device.id, expectedProtocol: 'V2' });
|
|
175
|
+
disconnectHandler?.(device);
|
|
176
|
+
|
|
177
|
+
expect(publicConnect).not.toHaveBeenCalled();
|
|
178
|
+
expect(publicDisconnect).not.toHaveBeenCalled();
|
|
179
|
+
expect(transportDisconnect).toHaveBeenCalledWith({
|
|
180
|
+
id: device.id,
|
|
181
|
+
connectId: device.id,
|
|
182
|
+
name: device.name,
|
|
183
|
+
});
|
|
184
|
+
});
|
|
185
|
+
|
|
134
186
|
test('detects Protocol V2 after Protocol V1 probe timeout', async () => {
|
|
135
187
|
const device = { id: 'unknown-pro2-id', name: 'Unknown BLE Device' };
|
|
136
188
|
const nobleBle = createNobleBle(device);
|
|
@@ -341,4 +393,52 @@ describe('ElectronBleTransport protocol detection', () => {
|
|
|
341
393
|
await transport.release(device.id);
|
|
342
394
|
}
|
|
343
395
|
});
|
|
396
|
+
|
|
397
|
+
test('preserves the active Protocol V2 link when the same schema is configured again', async () => {
|
|
398
|
+
const device = { id: 'stable-schema-pro2-id', name: 'OneKey Pro 2' };
|
|
399
|
+
const nobleBle = createNobleBle(device);
|
|
400
|
+
let notificationHandler: ((deviceId: string, data: string) => void) | undefined;
|
|
401
|
+
nobleBle.onNotification.mockImplementation(handler => {
|
|
402
|
+
notificationHandler = handler;
|
|
403
|
+
return jest.fn();
|
|
404
|
+
});
|
|
405
|
+
let responseSeq = 0;
|
|
406
|
+
nobleBle.write.mockImplementation(() => {
|
|
407
|
+
responseSeq += 1;
|
|
408
|
+
const response = ProtocolV2.encodeFrame(
|
|
409
|
+
schemas,
|
|
410
|
+
'Success',
|
|
411
|
+
{ message: 'ok' },
|
|
412
|
+
{ router: PROTOCOL_V2_CHANNEL_BLE_UART, seq: responseSeq }
|
|
413
|
+
);
|
|
414
|
+
setTimeout(() => notificationHandler?.(device.id, bytesToHex(response)), 0);
|
|
415
|
+
return Promise.resolve();
|
|
416
|
+
});
|
|
417
|
+
const bleTransport = configureTransport(nobleBle);
|
|
418
|
+
|
|
419
|
+
try {
|
|
420
|
+
await bleTransport.acquire({ uuid: device.id, expectedProtocol: 'V2' });
|
|
421
|
+
const invalidateAllLinks = jest.spyOn(
|
|
422
|
+
(bleTransport as any).protocolV2Links,
|
|
423
|
+
'invalidateAllLinks'
|
|
424
|
+
);
|
|
425
|
+
bleTransport.configureProtocolV2(protocolV2Schema);
|
|
426
|
+
await new Promise<void>(resolve => {
|
|
427
|
+
setTimeout(resolve, 0);
|
|
428
|
+
});
|
|
429
|
+
expect(invalidateAllLinks).not.toHaveBeenCalled();
|
|
430
|
+
await expect(
|
|
431
|
+
bleTransport.call(device.id, 'Ping', { message: 'same-schema' })
|
|
432
|
+
).resolves.toEqual({
|
|
433
|
+
type: 'Success',
|
|
434
|
+
message: { message: 'ok' },
|
|
435
|
+
});
|
|
436
|
+
const sentSeqs = nobleBle.write.mock.calls.map(([, hex]) =>
|
|
437
|
+
Number.parseInt(hex.slice(12, 14), 16)
|
|
438
|
+
);
|
|
439
|
+
expect(sentSeqs).toEqual([1, 2]);
|
|
440
|
+
} finally {
|
|
441
|
+
await bleTransport.release(device.id);
|
|
442
|
+
}
|
|
443
|
+
});
|
|
344
444
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"electron-ble-transport.d.ts","sourceRoot":"","sources":["../src/electron-ble-transport.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"electron-ble-transport.d.ts","sourceRoot":"","sources":["../src/electron-ble-transport.ts"],"names":[],"mappings":";AAqBA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAClE,OAAO,KAAK,EAAE,gBAAgB,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AACnG,OAAO,KAAK,YAAY,MAAM,QAAQ,CAAC;AAIvC,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;IAC/B,gBAAgB,CAAC,EAAE,YAAY,CAAC;CACjC,CAAC;AAoCF,MAAM,CAAC,OAAO,OAAO,oBAAoB;IACvC,OAAO,CAAC,SAAS,CAA0D;IAE3E,OAAO,CAAC,WAAW,CAA0D;IAE7E,OAAO,CAAC,6BAA6B,CAAqB;IAE1D,IAAI,SAA0B;IAE9B,UAAU,UAAS;IAEnB,UAAU,EAAE,QAAQ,CAAC,UAAU,GAAG,MAAM,CAAC,GAAG,IAAI,CAAQ;IAExD,GAAG,CAAC,EAAE,GAAG,CAAC;IAEV,OAAO,CAAC,EAAE,YAAY,CAAC;IAEvB,OAAO,CAAC,gBAAgB,CAA0B;IAElD,OAAO,CAAC,cAAc,CAAwC;IAE9D,OAAO,CAAC,mBAAmB,CAAwC;IAEnE,OAAO,CAAC,SAAS,CAAsE;IAEvF,OAAO,CAAC,YAAY,CAAoD;IAExE,OAAO,CAAC,aAAa,CAAwC;IAE7D,OAAO,CAAC,eAAe,CAAgD;IAEvE,OAAO,CAAC,eAAe,CAmBpB;IAEH,OAAO,CAAC,oBAAoB,CAAsC;IAElE,OAAO,CAAC,kBAAkB,CAAsC;IAEhE,OAAO,CAAC,kBAAkB,CAAkC;IAE5D,OAAO,CAAC,qBAAqB,CAAK;IAElC,OAAO,CAAC,oBAAoB;IA+B5B,OAAO,CAAC,kBAAkB;IA0B1B,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,YAAY;IAcxC,SAAS,CAAC,UAAU,EAAE,GAAG;IAKzB,mBAAmB,CAAC,UAAU,EAAE,GAAG;IAgB7B,MAAM;IAIN,SAAS,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAqBxC,OAAO,CAAC,KAAK,EAAE,eAAe;;;;;;;;;;;IAoF9B,OAAO,CAAC,EAAE,EAAE,MAAM;IAgBxB,OAAO,CAAC,2BAA2B;IAOnC,OAAO,CAAC,4BAA4B;IAOpC,OAAO,CAAC,kBAAkB;YAMZ,cAAc;IA+C5B,OAAO,CAAC,8BAA8B;YAgBxB,iCAAiC;YAqCjC,eAAe;YAgBf,eAAe;YAuBf,iBAAiB;YAsBjB,SAAS;IASvB,OAAO,CAAC,kBAAkB;IAwB1B,OAAO,CAAC,4BAA4B;IAkBpC,OAAO,CAAC,uBAAuB;IAS/B,OAAO,CAAC,sBAAsB;IAU9B,OAAO,CAAC,yBAAyB;IAQjC,OAAO,CAAC,qBAAqB;IAK7B,OAAO,CAAC,sBAAsB;YAShB,mBAAmB;IAiBjC,OAAO,CAAC,4BAA4B;IAgB9B,IAAI,CACR,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,CAAC,EAAE,oBAAoB;YA2BlB,cAAc;YAuEd,cAAc;IA0B5B,OAAO,CAAC,uBAAuB;IA0C/B,OAAO,CAAC,6BAA6B;IAsCrC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;CAGxD"}
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -873,10 +873,18 @@ class ElectronBleTransport {
|
|
|
873
873
|
this.configured = true;
|
|
874
874
|
}
|
|
875
875
|
configureProtocolV2(signedData) {
|
|
876
|
+
const configuration = typeof signedData === 'string' ? signedData : JSON.stringify(signedData);
|
|
877
|
+
if (this.protocolV2SchemaConfiguration === configuration) {
|
|
878
|
+
return;
|
|
879
|
+
}
|
|
880
|
+
const isReconfiguration = this.protocolV2SchemaConfiguration !== undefined;
|
|
876
881
|
this._messagesV2 = parseConfigure(signedData);
|
|
877
|
-
this.
|
|
878
|
-
|
|
879
|
-
|
|
882
|
+
this.protocolV2SchemaConfiguration = configuration;
|
|
883
|
+
if (isReconfiguration) {
|
|
884
|
+
this.protocolV2Links
|
|
885
|
+
.invalidateAllLinks('Protocol V2 schema reconfigured')
|
|
886
|
+
.catch(error => { var _a; return (_a = this.Log) === null || _a === void 0 ? void 0 : _a.debug('[Electron BLE] schema link cleanup failed:', error); });
|
|
887
|
+
}
|
|
880
888
|
}
|
|
881
889
|
listen() {
|
|
882
890
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -908,7 +916,7 @@ class ElectronBleTransport {
|
|
|
908
916
|
});
|
|
909
917
|
}
|
|
910
918
|
acquire(input) {
|
|
911
|
-
var _a, _b, _c, _d, _e
|
|
919
|
+
var _a, _b, _c, _d, _e;
|
|
912
920
|
return __awaiter(this, void 0, void 0, function* () {
|
|
913
921
|
const { uuid, forceCleanRunPromise, expectedProtocol } = input;
|
|
914
922
|
if (!uuid) {
|
|
@@ -953,7 +961,7 @@ class ElectronBleTransport {
|
|
|
953
961
|
var _a;
|
|
954
962
|
if (disconnectedDevice.id === uuid) {
|
|
955
963
|
this.cleanupDeviceState(uuid);
|
|
956
|
-
(_a = this.emitter) === null || _a === void 0 ? void 0 : _a.emit(
|
|
964
|
+
(_a = this.emitter) === null || _a === void 0 ? void 0 : _a.emit(transport.TRANSPORT_EVENT.DEVICE_DISCONNECT, {
|
|
957
965
|
name: disconnectedDevice.name,
|
|
958
966
|
id: disconnectedDevice.id,
|
|
959
967
|
connectId: disconnectedDevice.id,
|
|
@@ -962,23 +970,18 @@ class ElectronBleTransport {
|
|
|
962
970
|
});
|
|
963
971
|
this.disconnectCleanups.set(uuid, disconnectCleanup);
|
|
964
972
|
const protocolType = yield this.detectProtocol(uuid, expectedProtocol, protocolHint);
|
|
965
|
-
(_c = this.emitter) === null || _c === void 0 ? void 0 : _c.emit('device-connect', {
|
|
966
|
-
name: device.name,
|
|
967
|
-
id: device.id,
|
|
968
|
-
connectId: device.id,
|
|
969
|
-
});
|
|
970
973
|
return Object.assign(Object.assign({}, toBleDescriptor({ id: device.id, name: device.name }, protocolType)), { uuid });
|
|
971
974
|
}
|
|
972
975
|
catch (error) {
|
|
973
|
-
(
|
|
976
|
+
(_c = this.Log) === null || _c === void 0 ? void 0 : _c.error('[Electron BLE] acquire failed:', error);
|
|
974
977
|
try {
|
|
975
|
-
if (((
|
|
978
|
+
if (((_d = window.desktopApi) === null || _d === void 0 ? void 0 : _d.nobleBle) && this.connectedDevices.has(uuid)) {
|
|
976
979
|
yield window.desktopApi.nobleBle.unsubscribe(uuid);
|
|
977
980
|
yield window.desktopApi.nobleBle.disconnect(uuid);
|
|
978
981
|
}
|
|
979
982
|
}
|
|
980
983
|
catch (cleanupError) {
|
|
981
|
-
(
|
|
984
|
+
(_e = this.Log) === null || _e === void 0 ? void 0 : _e.debug('[Electron BLE] acquire cleanup failed:', cleanupError);
|
|
982
985
|
}
|
|
983
986
|
this.cleanupDeviceState(uuid);
|
|
984
987
|
throw error;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onekeyfe/hd-transport-web-device",
|
|
3
|
-
"version": "1.2.0-alpha.
|
|
3
|
+
"version": "1.2.0-alpha.24",
|
|
4
4
|
"author": "OneKey",
|
|
5
5
|
"homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
|
|
6
6
|
"license": "MIT",
|
|
@@ -20,13 +20,13 @@
|
|
|
20
20
|
"lint:fix": "eslint . --fix"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@onekeyfe/hd-shared": "1.2.0-alpha.
|
|
24
|
-
"@onekeyfe/hd-transport": "1.2.0-alpha.
|
|
23
|
+
"@onekeyfe/hd-shared": "1.2.0-alpha.24",
|
|
24
|
+
"@onekeyfe/hd-transport": "1.2.0-alpha.24"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"@onekeyfe/hd-transport-electron": "1.2.0-alpha.
|
|
27
|
+
"@onekeyfe/hd-transport-electron": "1.2.0-alpha.24",
|
|
28
28
|
"@types/w3c-web-usb": "^1.0.6",
|
|
29
29
|
"@types/web-bluetooth": "^0.0.17"
|
|
30
30
|
},
|
|
31
|
-
"gitHead": "
|
|
31
|
+
"gitHead": "43663337d94350430cc507c74d6eec5a076bd4e9"
|
|
32
32
|
}
|
|
@@ -3,6 +3,7 @@ import transport, {
|
|
|
3
3
|
PROTOCOL_V2_CHANNEL_BLE_UART,
|
|
4
4
|
ProtocolV2FrameAssembler,
|
|
5
5
|
ProtocolV2LinkManager,
|
|
6
|
+
TRANSPORT_EVENT,
|
|
6
7
|
bytesToHex,
|
|
7
8
|
hexToBytes,
|
|
8
9
|
probeProtocolV2 as probeProtocolV2Helper,
|
|
@@ -76,6 +77,8 @@ export default class ElectronBleTransport {
|
|
|
76
77
|
|
|
77
78
|
private _messagesV2: ReturnType<typeof transport.parseConfigure> | undefined;
|
|
78
79
|
|
|
80
|
+
private protocolV2SchemaConfiguration: string | undefined;
|
|
81
|
+
|
|
79
82
|
name = 'ElectronBleTransport';
|
|
80
83
|
|
|
81
84
|
configured = false;
|
|
@@ -206,10 +209,19 @@ export default class ElectronBleTransport {
|
|
|
206
209
|
}
|
|
207
210
|
|
|
208
211
|
configureProtocolV2(signedData: any) {
|
|
212
|
+
const configuration = typeof signedData === 'string' ? signedData : JSON.stringify(signedData);
|
|
213
|
+
if (this.protocolV2SchemaConfiguration === configuration) {
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const isReconfiguration = this.protocolV2SchemaConfiguration !== undefined;
|
|
209
218
|
this._messagesV2 = parseConfigure(signedData);
|
|
210
|
-
this.
|
|
211
|
-
|
|
212
|
-
|
|
219
|
+
this.protocolV2SchemaConfiguration = configuration;
|
|
220
|
+
if (isReconfiguration) {
|
|
221
|
+
this.protocolV2Links
|
|
222
|
+
.invalidateAllLinks('Protocol V2 schema reconfigured')
|
|
223
|
+
.catch(error => this.Log?.debug('[Electron BLE] schema link cleanup failed:', error));
|
|
224
|
+
}
|
|
213
225
|
}
|
|
214
226
|
|
|
215
227
|
async listen() {
|
|
@@ -290,7 +302,7 @@ export default class ElectronBleTransport {
|
|
|
290
302
|
(disconnectedDevice: any) => {
|
|
291
303
|
if (disconnectedDevice.id === uuid) {
|
|
292
304
|
this.cleanupDeviceState(uuid);
|
|
293
|
-
this.emitter?.emit(
|
|
305
|
+
this.emitter?.emit(TRANSPORT_EVENT.DEVICE_DISCONNECT, {
|
|
294
306
|
name: disconnectedDevice.name,
|
|
295
307
|
id: disconnectedDevice.id,
|
|
296
308
|
connectId: disconnectedDevice.id,
|
|
@@ -302,12 +314,6 @@ export default class ElectronBleTransport {
|
|
|
302
314
|
|
|
303
315
|
const protocolType = await this.detectProtocol(uuid, expectedProtocol, protocolHint);
|
|
304
316
|
|
|
305
|
-
this.emitter?.emit('device-connect', {
|
|
306
|
-
name: device.name,
|
|
307
|
-
id: device.id,
|
|
308
|
-
connectId: device.id,
|
|
309
|
-
});
|
|
310
|
-
|
|
311
317
|
return {
|
|
312
318
|
...toBleDescriptor({ id: device.id, name: device.name }, protocolType),
|
|
313
319
|
uuid,
|