@onekeyfe/hd-transport-lowlevel 1.1.27-alpha.34 → 1.1.27-alpha.36

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.
@@ -124,16 +124,35 @@ describe('LowlevelTransport protocol framing', () => {
124
124
  }).map(chunk => chunk.toString('hex'));
125
125
  const plugin = createPlugin({
126
126
  devices: [{ id: 'classic-id', name: 'OneKey Classic', commType: 'ble' }],
127
- responses: responseChunks,
127
+ responses: [...responseChunks, ...responseChunks],
128
128
  });
129
129
  const lowlevel = configureTransport(plugin);
130
130
 
131
+ await expect(lowlevel.acquire({ uuid: 'classic-id' })).resolves.toEqual({
132
+ uuid: 'classic-id',
133
+ protocolType: 'V1',
134
+ });
131
135
  await expect(lowlevel.call('classic-id', 'Initialize', {})).resolves.toEqual({
132
136
  type: 'Success',
133
137
  message: { message: 'ok' },
134
138
  });
135
139
  });
136
140
 
141
+ test('rejects calls before protocol detection', async () => {
142
+ const responseChunks = ProtocolV1.encodeTransportPackets(schemas.protocolV1, 'Success', {
143
+ message: 'ok',
144
+ }).map(chunk => chunk.toString('hex'));
145
+ const plugin = createPlugin({
146
+ devices: [{ id: 'classic-id', name: 'OneKey Classic', commType: 'ble' }],
147
+ responses: responseChunks,
148
+ });
149
+ const lowlevel = configureTransport(plugin);
150
+
151
+ await expect(lowlevel.call('classic-id', 'Initialize', {})).rejects.toThrow(
152
+ 'Device protocol has not been detected'
153
+ );
154
+ });
155
+
137
156
  test('detects Protocol V2 devices and reassembles split Protocol V2 notifications', async () => {
138
157
  const probeResponse = ProtocolV2.encodeFrame(
139
158
  schemas,
@@ -250,4 +269,20 @@ describe('LowlevelTransport protocol framing', () => {
250
269
  'Device protocol mismatch: expected V1'
251
270
  );
252
271
  });
272
+
273
+ test('rejects automatic detection instead of caching V1 when both protocol probes fail', async () => {
274
+ const plugin = createPlugin({
275
+ devices: [{ id: 'flaky-pro2-id', name: 'Unknown BLE Device', commType: 'ble' }],
276
+ responses: [
277
+ new Error('Protocol V1 probe timed out'),
278
+ new Error('Protocol V2 probe timed out'),
279
+ ],
280
+ });
281
+ const lowlevel = configureTransport(plugin);
282
+
283
+ await expect(lowlevel.acquire({ uuid: 'flaky-pro2-id' })).rejects.toThrow(
284
+ 'Unable to detect BLE protocol'
285
+ );
286
+ expect(lowlevel.getProtocolType('flaky-pro2-id')).toBeUndefined();
287
+ });
253
288
  });
package/dist/index.d.ts CHANGED
@@ -17,7 +17,7 @@ declare class LowlevelTransport {
17
17
  private deviceProtocol;
18
18
  private deviceProtocolHints;
19
19
  private protocolV2Assemblers;
20
- getProtocolType(path: string): ProtocolType;
20
+ getProtocolType(path: string): ProtocolType | undefined;
21
21
  init(logger: any, emitter: EventEmitter, plugin: LowlevelTransportSharedPlugin): void;
22
22
  configure(signedData: any): void;
23
23
  configureProtocolV2(signedData: any): void;
@@ -32,6 +32,8 @@ declare class LowlevelTransport {
32
32
  private callProtocolV1;
33
33
  private createProtocolTimeoutError;
34
34
  private createProtocolMismatchError;
35
+ private createProtocolDetectionError;
36
+ private clearProbeProtocol;
35
37
  private detectProtocol;
36
38
  private resetConnectionAfterProbe;
37
39
  private probeProtocolV1;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,SAWN,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,YAAY,MAAM,QAAQ,CAAC;AACvC,OAAO,KAAK,EACV,cAAc,EACd,6BAA6B,EAC7B,YAAY,EACZ,oBAAoB,EACrB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAqBpD,MAAM,CAAC,OAAO,OAAO,iBAAiB;IACpC,SAAS,EAAE,UAAU,CAAC,OAAO,SAAS,CAAC,cAAc,CAAC,GAAG,SAAS,CAAC;IAEnE,WAAW,EAAE,UAAU,CAAC,OAAO,SAAS,CAAC,cAAc,CAAC,GAAG,SAAS,CAAC;IAErE,UAAU,UAAS;IAEnB,GAAG,CAAC,EAAE,GAAG,CAAC;IAEV,OAAO,CAAC,EAAE,YAAY,CAAC;IAEvB,MAAM,EAAE,6BAA6B,CAAuC;IAE5E,OAAO,CAAC,cAAc,CAAwC;IAE9D,OAAO,CAAC,mBAAmB,CAAwC;IAEnE,OAAO,CAAC,oBAAoB,CAAoD;IAEhF,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY;IAI3C,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,6BAA6B;IAO9E,SAAS,CAAC,UAAU,EAAE,GAAG;IAMzB,mBAAmB,CAAC,UAAU,EAAE,GAAG;IAInC,MAAM;IAIA,SAAS;IAWT,OAAO,CAAC,KAAK,EAAE,oBAAoB;;;;IAuBnC,OAAO,CAAC,IAAI,EAAE,MAAM;IAapB,IAAI,CACR,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,CAAC,EAAE,oBAAoB;YA6BlB,cAAc;IAuC5B,OAAO,CAAC,0BAA0B;IAOlC,OAAO,CAAC,2BAA2B;YAOrB,cAAc;YAiDd,yBAAyB;YA0BzB,eAAe;YAef,eAAe;YAoBf,UAAU;YAUV,qBAAqB;YAmBrB,mBAAmB;YAqBnB,oBAAoB;YAOpB,cAAc;IAsC5B,MAAM;CAGP"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,SAWN,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,YAAY,MAAM,QAAQ,CAAC;AACvC,OAAO,KAAK,EACV,cAAc,EACd,6BAA6B,EAC7B,YAAY,EACZ,oBAAoB,EACrB,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAqBpD,MAAM,CAAC,OAAO,OAAO,iBAAiB;IACpC,SAAS,EAAE,UAAU,CAAC,OAAO,SAAS,CAAC,cAAc,CAAC,GAAG,SAAS,CAAC;IAEnE,WAAW,EAAE,UAAU,CAAC,OAAO,SAAS,CAAC,cAAc,CAAC,GAAG,SAAS,CAAC;IAErE,UAAU,UAAS;IAEnB,GAAG,CAAC,EAAE,GAAG,CAAC;IAEV,OAAO,CAAC,EAAE,YAAY,CAAC;IAEvB,MAAM,EAAE,6BAA6B,CAAuC;IAE5E,OAAO,CAAC,cAAc,CAAwC;IAE9D,OAAO,CAAC,mBAAmB,CAAwC;IAEnE,OAAO,CAAC,oBAAoB,CAAoD;IAEhF,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAIvD,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,6BAA6B;IAO9E,SAAS,CAAC,UAAU,EAAE,GAAG;IAMzB,mBAAmB,CAAC,UAAU,EAAE,GAAG;IAInC,MAAM;IAIA,SAAS;IAWT,OAAO,CAAC,KAAK,EAAE,oBAAoB;;;;IAuBnC,OAAO,CAAC,IAAI,EAAE,MAAM;IAapB,IAAI,CACR,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,CAAC,EAAE,oBAAoB;YAmClB,cAAc;IAuC5B,OAAO,CAAC,0BAA0B;IAOlC,OAAO,CAAC,2BAA2B;IAOnC,OAAO,CAAC,4BAA4B;IAOpC,OAAO,CAAC,kBAAkB;YAMZ,cAAc;YAsDd,yBAAyB;YA0BzB,eAAe;YAgBf,eAAe;YA6Bf,UAAU;YAUV,qBAAqB;YAmBrB,mBAAmB;YAqBnB,oBAAoB;YAOpB,cAAc;IAsC5B,MAAM;CAGP"}
package/dist/index.js CHANGED
@@ -60,8 +60,7 @@ class LowlevelTransport {
60
60
  this.protocolV2Assemblers = new Map();
61
61
  }
62
62
  getProtocolType(path) {
63
- var _a;
64
- return (_a = this.deviceProtocol.get(path)) !== null && _a !== void 0 ? _a : 'V1';
63
+ return this.deviceProtocol.get(path);
65
64
  }
66
65
  init(logger, emitter, plugin) {
67
66
  this.Log = logger;
@@ -130,6 +129,9 @@ class LowlevelTransport {
130
129
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.TransportNotConfigured);
131
130
  }
132
131
  const protocol = this.getProtocolType(uuid);
132
+ if (!protocol) {
133
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Device protocol has not been detected for ${uuid}`);
134
+ }
133
135
  if (transport.LogBlockCommand.has(name)) {
134
136
  this.Log.debug('lowlevel-transport', 'call-', ' name: ', name, ' protocol: ', protocol);
135
137
  }
@@ -183,8 +185,16 @@ class LowlevelTransport {
183
185
  createProtocolMismatchError(expected) {
184
186
  return hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `Device protocol mismatch: expected ${expected}, but device did not respond to expected protocol`);
185
187
  }
188
+ createProtocolDetectionError() {
189
+ return hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.BleTimeoutError, 'Unable to detect BLE protocol: device did not respond to Protocol V1 Initialize or Protocol V2 Ping');
190
+ }
191
+ clearProbeProtocol(uuid, protocol) {
192
+ if (this.deviceProtocol.get(uuid) === protocol) {
193
+ this.deviceProtocol.delete(uuid);
194
+ }
195
+ }
186
196
  detectProtocol(uuid, expectedProtocol, protocolHint) {
187
- var _a, _b, _c, _d, _e;
197
+ var _a, _b, _c, _d, _e, _f;
188
198
  return __awaiter(this, void 0, void 0, function* () {
189
199
  if (expectedProtocol === 'V2') {
190
200
  if (yield this.probeProtocolV2(uuid)) {
@@ -213,17 +223,20 @@ class LowlevelTransport {
213
223
  (_d = this.Log) === null || _d === void 0 ? void 0 : _d.debug(`[LowlevelTransport] detectProtocol: uuid=${uuid} -> V2 (cached)`);
214
224
  return 'V2';
215
225
  }
216
- let protocol = 'V1';
217
226
  const protocolV1Detected = yield this.probeProtocolV1(uuid);
218
- if (!protocolV1Detected) {
219
- yield this.resetConnectionAfterProbe(uuid, 'V1');
220
- if (yield this.probeProtocolV2(uuid)) {
221
- protocol = 'V2';
222
- }
227
+ if (protocolV1Detected) {
228
+ this.deviceProtocol.set(uuid, 'V1');
229
+ (_e = this.Log) === null || _e === void 0 ? void 0 : _e.debug(`[LowlevelTransport] detectProtocol: uuid=${uuid} -> V1`);
230
+ return 'V1';
231
+ }
232
+ yield this.resetConnectionAfterProbe(uuid, 'V1');
233
+ if (yield this.probeProtocolV2(uuid)) {
234
+ this.deviceProtocol.set(uuid, 'V2');
235
+ (_f = this.Log) === null || _f === void 0 ? void 0 : _f.debug(`[LowlevelTransport] detectProtocol: uuid=${uuid} -> V2`);
236
+ return 'V2';
223
237
  }
224
- this.deviceProtocol.set(uuid, protocol);
225
- (_e = this.Log) === null || _e === void 0 ? void 0 : _e.debug(`[LowlevelTransport] detectProtocol: uuid=${uuid} -> ${protocol}`);
226
- return protocol;
238
+ this.deviceProtocol.delete(uuid);
239
+ throw this.createProtocolDetectionError();
227
240
  });
228
241
  }
229
242
  resetConnectionAfterProbe(uuid, protocol) {
@@ -257,6 +270,7 @@ class LowlevelTransport {
257
270
  return true;
258
271
  }
259
272
  catch (error) {
273
+ this.clearProbeProtocol(uuid, 'V1');
260
274
  (_a = this.Log) === null || _a === void 0 ? void 0 : _a.debug('[LowlevelTransport] Protocol V1 Initialize probe failed:', error);
261
275
  return false;
262
276
  }
@@ -270,17 +284,27 @@ class LowlevelTransport {
270
284
  }
271
285
  this.deviceProtocol.set(uuid, 'V2');
272
286
  (_a = this.protocolV2Assemblers.get(uuid)) === null || _a === void 0 ? void 0 : _a.reset();
273
- return transport.probeProtocolV2({
274
- call: (name, data, options) => this.callProtocolV2(uuid, name, data, options),
275
- timeoutMs: PROTOCOL_V2_PROBE_TIMEOUT_MS,
276
- logger: this.Log,
277
- logPrefix: 'ProtocolV2 Lowlevel-BLE',
278
- onProbeFailed: () => __awaiter(this, void 0, void 0, function* () {
279
- var _b;
280
- (_b = this.protocolV2Assemblers.get(uuid)) === null || _b === void 0 ? void 0 : _b.reset();
281
- yield this.resetConnectionAfterProbe(uuid, 'V2');
282
- }),
283
- });
287
+ try {
288
+ const detected = yield transport.probeProtocolV2({
289
+ call: (name, data, options) => this.callProtocolV2(uuid, name, data, options),
290
+ timeoutMs: PROTOCOL_V2_PROBE_TIMEOUT_MS,
291
+ logger: this.Log,
292
+ logPrefix: 'ProtocolV2 Lowlevel-BLE',
293
+ onProbeFailed: () => __awaiter(this, void 0, void 0, function* () {
294
+ var _b;
295
+ (_b = this.protocolV2Assemblers.get(uuid)) === null || _b === void 0 ? void 0 : _b.reset();
296
+ yield this.resetConnectionAfterProbe(uuid, 'V2');
297
+ }),
298
+ });
299
+ if (!detected) {
300
+ this.clearProbeProtocol(uuid, 'V2');
301
+ }
302
+ return detected;
303
+ }
304
+ catch (error) {
305
+ this.clearProbeProtocol(uuid, 'V2');
306
+ throw error;
307
+ }
284
308
  });
285
309
  }
286
310
  receiveHex(timeoutMs, commandName) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/hd-transport-lowlevel",
3
- "version": "1.1.27-alpha.34",
3
+ "version": "1.1.27-alpha.36",
4
4
  "homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.js",
@@ -20,8 +20,8 @@
20
20
  "lint:fix": "eslint . --fix"
21
21
  },
22
22
  "dependencies": {
23
- "@onekeyfe/hd-shared": "1.1.27-alpha.34",
24
- "@onekeyfe/hd-transport": "1.1.27-alpha.34"
23
+ "@onekeyfe/hd-shared": "1.1.27-alpha.36",
24
+ "@onekeyfe/hd-transport": "1.1.27-alpha.36"
25
25
  },
26
- "gitHead": "ff1863a1ff300ada1314b7315e5ab827663d9f4c"
26
+ "gitHead": "1aaff42d7dd10933009ba7e0c0b7324e91d8e993"
27
27
  }
package/src/index.ts CHANGED
@@ -59,8 +59,8 @@ export default class LowlevelTransport {
59
59
 
60
60
  private protocolV2Assemblers: Map<string, ProtocolV2FrameAssembler> = new Map();
61
61
 
62
- getProtocolType(path: string): ProtocolType {
63
- return this.deviceProtocol.get(path) ?? 'V1';
62
+ getProtocolType(path: string): ProtocolType | undefined {
63
+ return this.deviceProtocol.get(path);
64
64
  }
65
65
 
66
66
  init(logger: any, emitter: EventEmitter, plugin: LowlevelTransportSharedPlugin) {
@@ -142,6 +142,12 @@ export default class LowlevelTransport {
142
142
  }
143
143
 
144
144
  const protocol = this.getProtocolType(uuid);
145
+ if (!protocol) {
146
+ throw ERRORS.TypedError(
147
+ HardwareErrorCode.RuntimeError,
148
+ `Device protocol has not been detected for ${uuid}`
149
+ );
150
+ }
145
151
  if (LogBlockCommand.has(name)) {
146
152
  this.Log.debug('lowlevel-transport', 'call-', ' name: ', name, ' protocol: ', protocol);
147
153
  } else {
@@ -217,6 +223,19 @@ export default class LowlevelTransport {
217
223
  );
218
224
  }
219
225
 
226
+ private createProtocolDetectionError() {
227
+ return ERRORS.TypedError(
228
+ HardwareErrorCode.BleTimeoutError,
229
+ 'Unable to detect BLE protocol: device did not respond to Protocol V1 Initialize or Protocol V2 Ping'
230
+ );
231
+ }
232
+
233
+ private clearProbeProtocol(uuid: string, protocol: ProtocolType) {
234
+ if (this.deviceProtocol.get(uuid) === protocol) {
235
+ this.deviceProtocol.delete(uuid);
236
+ }
237
+ }
238
+
220
239
  private async detectProtocol(
221
240
  uuid: string,
222
241
  expectedProtocol?: ProtocolType,
@@ -253,17 +272,22 @@ export default class LowlevelTransport {
253
272
  return 'V2';
254
273
  }
255
274
 
256
- let protocol: ProtocolType = 'V1';
257
275
  const protocolV1Detected = await this.probeProtocolV1(uuid);
258
- if (!protocolV1Detected) {
259
- await this.resetConnectionAfterProbe(uuid, 'V1');
260
- if (await this.probeProtocolV2(uuid)) {
261
- protocol = 'V2';
262
- }
276
+ if (protocolV1Detected) {
277
+ this.deviceProtocol.set(uuid, 'V1');
278
+ this.Log?.debug(`[LowlevelTransport] detectProtocol: uuid=${uuid} -> V1`);
279
+ return 'V1';
263
280
  }
264
- this.deviceProtocol.set(uuid, protocol);
265
- this.Log?.debug(`[LowlevelTransport] detectProtocol: uuid=${uuid} -> ${protocol}`);
266
- return protocol;
281
+
282
+ await this.resetConnectionAfterProbe(uuid, 'V1');
283
+ if (await this.probeProtocolV2(uuid)) {
284
+ this.deviceProtocol.set(uuid, 'V2');
285
+ this.Log?.debug(`[LowlevelTransport] detectProtocol: uuid=${uuid} -> V2`);
286
+ return 'V2';
287
+ }
288
+
289
+ this.deviceProtocol.delete(uuid);
290
+ throw this.createProtocolDetectionError();
267
291
  }
268
292
 
269
293
  private async resetConnectionAfterProbe(uuid: string, protocol: ProtocolType) {
@@ -302,6 +326,7 @@ export default class LowlevelTransport {
302
326
  await this.callProtocolV1(uuid, 'Initialize', {}, { timeoutMs: PROTOCOL_PROBE_TIMEOUT_MS });
303
327
  return true;
304
328
  } catch (error) {
329
+ this.clearProbeProtocol(uuid, 'V1');
305
330
  this.Log?.debug('[LowlevelTransport] Protocol V1 Initialize probe failed:', error);
306
331
  return false;
307
332
  }
@@ -314,17 +339,26 @@ export default class LowlevelTransport {
314
339
 
315
340
  this.deviceProtocol.set(uuid, 'V2');
316
341
  this.protocolV2Assemblers.get(uuid)?.reset();
317
- return probeProtocolV2Helper({
318
- call: (name: string, data: Record<string, unknown>, options?: TransportCallOptions) =>
319
- this.callProtocolV2(uuid, name, data, options),
320
- timeoutMs: PROTOCOL_V2_PROBE_TIMEOUT_MS,
321
- logger: this.Log,
322
- logPrefix: 'ProtocolV2 Lowlevel-BLE',
323
- onProbeFailed: async () => {
324
- this.protocolV2Assemblers.get(uuid)?.reset();
325
- await this.resetConnectionAfterProbe(uuid, 'V2');
326
- },
327
- });
342
+ try {
343
+ const detected = await probeProtocolV2Helper({
344
+ call: (name: string, data: Record<string, unknown>, options?: TransportCallOptions) =>
345
+ this.callProtocolV2(uuid, name, data, options),
346
+ timeoutMs: PROTOCOL_V2_PROBE_TIMEOUT_MS,
347
+ logger: this.Log,
348
+ logPrefix: 'ProtocolV2 Lowlevel-BLE',
349
+ onProbeFailed: async () => {
350
+ this.protocolV2Assemblers.get(uuid)?.reset();
351
+ await this.resetConnectionAfterProbe(uuid, 'V2');
352
+ },
353
+ });
354
+ if (!detected) {
355
+ this.clearProbeProtocol(uuid, 'V2');
356
+ }
357
+ return detected;
358
+ } catch (error) {
359
+ this.clearProbeProtocol(uuid, 'V2');
360
+ throw error;
361
+ }
328
362
  }
329
363
 
330
364
  private async receiveHex(timeoutMs: number | undefined, commandName: string) {