@onekeyfe/hd-transport 1.2.0-alpha.0 → 1.2.0-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.
Files changed (44) hide show
  1. package/README.md +1 -1
  2. package/__tests__/messages.test.js +76 -0
  3. package/__tests__/protocol-v2-link-manager.test.js +326 -0
  4. package/__tests__/protocol-v2-usb-transport-base.test.js +296 -0
  5. package/__tests__/protocol-v2.test.js +252 -84
  6. package/dist/constants.d.ts +4 -2
  7. package/dist/constants.d.ts.map +1 -1
  8. package/dist/index.d.ts +564 -326
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +434 -102
  11. package/dist/protocols/index.d.ts +2 -0
  12. package/dist/protocols/index.d.ts.map +1 -1
  13. package/dist/protocols/v2/constants.d.ts +1 -0
  14. package/dist/protocols/v2/constants.d.ts.map +1 -1
  15. package/dist/protocols/v2/decode.d.ts +1 -0
  16. package/dist/protocols/v2/decode.d.ts.map +1 -1
  17. package/dist/protocols/v2/link-manager.d.ts +35 -0
  18. package/dist/protocols/v2/link-manager.d.ts.map +1 -0
  19. package/dist/protocols/v2/sequence-cursor.d.ts +5 -0
  20. package/dist/protocols/v2/sequence-cursor.d.ts.map +1 -0
  21. package/dist/protocols/v2/session.d.ts +16 -4
  22. package/dist/protocols/v2/session.d.ts.map +1 -1
  23. package/dist/protocols/v2/usb-transport-base.d.ts +31 -0
  24. package/dist/protocols/v2/usb-transport-base.d.ts.map +1 -0
  25. package/dist/serialization/protobuf/messages.d.ts.map +1 -1
  26. package/dist/types/messages.d.ts +337 -221
  27. package/dist/types/messages.d.ts.map +1 -1
  28. package/dist/types/transport.d.ts +1 -1
  29. package/dist/types/transport.d.ts.map +1 -1
  30. package/messages-protocol-v2.json +992 -1420
  31. package/package.json +2 -2
  32. package/scripts/protobuf-build.sh +60 -142
  33. package/src/constants.ts +8 -2
  34. package/src/index.ts +8 -0
  35. package/src/protocols/index.ts +4 -1
  36. package/src/protocols/v2/constants.ts +1 -0
  37. package/src/protocols/v2/decode.ts +36 -17
  38. package/src/protocols/v2/link-manager.ts +160 -0
  39. package/src/protocols/v2/sequence-cursor.ts +10 -0
  40. package/src/protocols/v2/session.ts +86 -51
  41. package/src/protocols/v2/usb-transport-base.ts +194 -0
  42. package/src/serialization/protobuf/messages.ts +6 -1
  43. package/src/types/messages.ts +419 -272
  44. package/src/types/transport.ts +1 -1
@@ -1,8 +1,12 @@
1
1
  const { ProtocolV2 } = require('../src/protocols');
2
2
  const { parseConfigure } = require('../src/serialization/protobuf/messages');
3
- const sessionModule = require('../src/protocols/v2/session');
4
-
5
- const { ProtocolV2FrameAssembler, ProtocolV2Session, probeProtocolV2 } = sessionModule;
3
+ const {
4
+ ProtocolV2FrameAssembler,
5
+ ProtocolV2SequenceCursor,
6
+ ProtocolV2Session,
7
+ hexToBytes,
8
+ probeProtocolV2,
9
+ } = require('../src/protocols/v2/session');
6
10
  const protocolV2 = require('../src/protocols/v2');
7
11
 
8
12
  const protocolV1Messages = parseConfigure({
@@ -15,6 +19,18 @@ const protocolV1Messages = parseConfigure({
15
19
  },
16
20
  },
17
21
  },
22
+ Failure: {
23
+ fields: {
24
+ code: {
25
+ type: 'uint32',
26
+ id: 1,
27
+ },
28
+ message: {
29
+ type: 'string',
30
+ id: 2,
31
+ },
32
+ },
33
+ },
18
34
  ButtonRequest: {
19
35
  fields: {
20
36
  code: {
@@ -32,6 +48,7 @@ const protocolV1Messages = parseConfigure({
32
48
  MessageType: {
33
49
  values: {
34
50
  MessageType_Success: 2,
51
+ MessageType_Failure: 3,
35
52
  MessageType_ButtonRequest: 26,
36
53
  MessageType_OnekeyGetFeatures: 10025,
37
54
  MessageType_OnekeyFeatures: 10026,
@@ -42,21 +59,22 @@ const protocolV1Messages = parseConfigure({
42
59
 
43
60
  const protocolV2Messages = parseConfigure({
44
61
  nested: {
45
- GetProtoVersion: {
62
+ ProtocolInfoRequest: {
46
63
  fields: {},
47
64
  },
48
- ProtoVersion: {
65
+ ProtocolInfo: {
49
66
  fields: {
50
- major_version: {
67
+ version: {
51
68
  type: 'uint32',
52
69
  id: 1,
53
70
  },
54
- minor_version: {
71
+ supported_messages: {
55
72
  type: 'uint32',
56
73
  id: 2,
74
+ rule: 'repeated',
57
75
  },
58
- patch_version: {
59
- type: 'uint32',
76
+ protobuf_definition: {
77
+ type: 'string',
60
78
  id: 3,
61
79
  },
62
80
  },
@@ -77,18 +95,53 @@ const protocolV2Messages = parseConfigure({
77
95
  },
78
96
  },
79
97
  },
80
- DevFirmwareUpdate: {
81
- fields: {},
98
+ DeviceFirmwareTarget: {
99
+ fields: {
100
+ target_id: {
101
+ type: 'uint32',
102
+ id: 1,
103
+ },
104
+ path: {
105
+ type: 'string',
106
+ id: 2,
107
+ },
108
+ },
109
+ },
110
+ DeviceFirmwareUpdateRequest: {
111
+ fields: {
112
+ targets: {
113
+ type: 'DeviceFirmwareTarget',
114
+ id: 1,
115
+ rule: 'repeated',
116
+ },
117
+ },
82
118
  },
83
- DevFirmwareInstallProgress: {
119
+ DeviceFirmwareUpdateRecord: {
84
120
  fields: {
85
121
  target_id: {
86
122
  type: 'uint32',
87
123
  id: 1,
88
124
  },
89
- progress: {
125
+ status: {
90
126
  type: 'uint32',
91
- id: 2,
127
+ id: 10,
128
+ },
129
+ payload_version: {
130
+ type: 'uint32',
131
+ id: 20,
132
+ },
133
+ path: {
134
+ type: 'string',
135
+ id: 30,
136
+ },
137
+ },
138
+ },
139
+ DeviceFirmwareUpdateStatus: {
140
+ fields: {
141
+ records: {
142
+ type: 'DeviceFirmwareUpdateRecord',
143
+ id: 1,
144
+ rule: 'repeated',
92
145
  },
93
146
  },
94
147
  },
@@ -117,13 +170,13 @@ const protocolV2Messages = parseConfigure({
117
170
  },
118
171
  MessageType: {
119
172
  values: {
120
- MessageType_GetProtoVersion: 60200,
121
- MessageType_ProtoVersion: 60201,
173
+ MessageType_ProtocolInfoRequest: 60200,
174
+ MessageType_ProtocolInfo: 60201,
122
175
  MessageType_Ping: 60206,
123
176
  MessageType_Success: 60207,
124
177
  MessageType_FileWrite: 60805,
125
- MessageType_DevFirmwareUpdate: 61000,
126
- MessageType_DevFirmwareInstallProgress: 61001,
178
+ MessageType_DeviceFirmwareUpdateRequest: 61000,
179
+ MessageType_DeviceFirmwareUpdateStatus: 61002,
127
180
  MessageType_PartialNested: 62000,
128
181
  },
129
182
  },
@@ -144,10 +197,10 @@ const rewriteSeq = (frame, seq) => {
144
197
 
145
198
  describe('Protocol V2 framing and session', () => {
146
199
  test('encodes and decodes Protocol V2 protobuf frames', () => {
147
- const frame = ProtocolV2.encodeFrame(schemas, 'ProtoVersion', {
148
- major_version: 1,
149
- minor_version: 2,
150
- patch_version: 3,
200
+ const frame = ProtocolV2.encodeFrame(schemas, 'ProtocolInfo', {
201
+ version: 1,
202
+ supported_messages: [60200, 60201],
203
+ protobuf_definition: 'proto',
151
204
  });
152
205
 
153
206
  const parsed = protocolV2.decodeFrame(frame);
@@ -155,15 +208,15 @@ describe('Protocol V2 framing and session', () => {
155
208
 
156
209
  const decoded = ProtocolV2.decodeFrame(schemas, frame);
157
210
  expect(decoded).toEqual({
158
- type: 'ProtoVersion',
159
- messageName: 'ProtoVersion',
211
+ type: 'ProtocolInfo',
212
+ messageName: 'ProtocolInfo',
160
213
  messageTypeId: 60201,
161
214
  pbPayload: parsed.pbPayload,
162
215
  seq: parsed.seq,
163
216
  message: {
164
- major_version: 1,
165
- minor_version: 2,
166
- patch_version: 3,
217
+ version: 1,
218
+ supported_messages: [60200, 60201],
219
+ protobuf_definition: 'proto',
167
220
  },
168
221
  });
169
222
  });
@@ -201,10 +254,9 @@ describe('Protocol V2 framing and session', () => {
201
254
  });
202
255
 
203
256
  test('reassembles split Protocol V2 frames and rejects oversized frames', () => {
204
- const frame = ProtocolV2.encodeFrame(schemas, 'ProtoVersion', {
205
- major_version: 1,
206
- minor_version: 0,
207
- patch_version: 0,
257
+ const frame = ProtocolV2.encodeFrame(schemas, 'ProtocolInfo', {
258
+ version: 1,
259
+ supported_messages: [],
208
260
  });
209
261
  const assembler = new ProtocolV2FrameAssembler();
210
262
 
@@ -216,15 +268,13 @@ describe('Protocol V2 framing and session', () => {
216
268
  });
217
269
 
218
270
  test('keeps bytes after the first complete frame for the next read', () => {
219
- const first = ProtocolV2.encodeFrame(schemas, 'ProtoVersion', {
220
- major_version: 1,
221
- minor_version: 0,
222
- patch_version: 0,
271
+ const first = ProtocolV2.encodeFrame(schemas, 'ProtocolInfo', {
272
+ version: 1,
273
+ supported_messages: [],
223
274
  });
224
- const second = ProtocolV2.encodeFrame(schemas, 'ProtoVersion', {
225
- major_version: 2,
226
- minor_version: 0,
227
- patch_version: 0,
275
+ const second = ProtocolV2.encodeFrame(schemas, 'ProtocolInfo', {
276
+ version: 2,
277
+ supported_messages: [],
228
278
  });
229
279
  const assembler = new ProtocolV2FrameAssembler();
230
280
  const combined = new Uint8Array(first.length + second.length);
@@ -237,10 +287,9 @@ describe('Protocol V2 framing and session', () => {
237
287
 
238
288
  test('session writes one encoded frame and decodes the response frame', async () => {
239
289
  const written = [];
240
- const response = ProtocolV2.encodeFrame(schemas, 'ProtoVersion', {
241
- major_version: 2,
242
- minor_version: 0,
243
- patch_version: 1,
290
+ const response = ProtocolV2.encodeFrame(schemas, 'ProtocolInfo', {
291
+ version: 2,
292
+ supported_messages: [60206],
244
293
  });
245
294
  const session = new ProtocolV2Session({
246
295
  schemas,
@@ -253,22 +302,72 @@ describe('Protocol V2 framing and session', () => {
253
302
  Promise.resolve(rewriteSeq(response, protocolV2.decodeFrame(written[0]).seq)),
254
303
  });
255
304
 
256
- const result = await session.call('GetProtoVersion', {});
305
+ const result = await session.call('ProtocolInfoRequest', {});
257
306
 
258
307
  expect(written).toHaveLength(1);
259
308
  expect(written[0][4]).toBe(1);
260
309
  expect(written[0][5]).toBe(0);
261
310
  expect(protocolV2.decodeFrame(written[0]).messageTypeId).toBe(60200);
262
311
  expect(result).toEqual({
263
- type: 'ProtoVersion',
312
+ type: 'ProtocolInfo',
264
313
  message: {
265
- major_version: 2,
266
- minor_version: 0,
267
- patch_version: 1,
314
+ version: 2,
315
+ supported_messages: [60206],
316
+ protobuf_definition: null,
268
317
  },
269
318
  });
270
319
  });
271
320
 
321
+ test('session skips Proto Link ACK frames before decoding the protobuf response', async () => {
322
+ const ack = new Uint8Array(8);
323
+ ack[0] = 0x5a;
324
+ ack[1] = 8;
325
+ ack[2] = 0;
326
+ ack[4] = 1;
327
+ ack[5] = 1;
328
+ ack[6] = 1;
329
+ ack[3] = protocolV2.crc8(ack, 3);
330
+ ack[7] = protocolV2.crc8(ack, 7);
331
+
332
+ const response = ProtocolV2.encodeFrame(schemas, 'Success', {
333
+ message: 'ok',
334
+ });
335
+ const readFrame = jest.fn().mockResolvedValueOnce(ack).mockResolvedValueOnce(response);
336
+ const session = new ProtocolV2Session({
337
+ schemas,
338
+ router: 1,
339
+ writeFrame: () => Promise.resolve(),
340
+ readFrame,
341
+ });
342
+
343
+ await expect(session.call('Ping', { message: 'hello' })).resolves.toEqual({
344
+ type: 'Success',
345
+ message: {
346
+ message: 'ok',
347
+ },
348
+ });
349
+ expect(readFrame).toHaveBeenCalledTimes(2);
350
+ });
351
+
352
+ test('session rejects BLE frames above its configured frame limit before writing', async () => {
353
+ const writeFrame = jest.fn().mockResolvedValue(undefined);
354
+ const response = ProtocolV2.encodeFrame(schemas, 'Success', {
355
+ message: 'ok',
356
+ });
357
+ const session = new ProtocolV2Session({
358
+ schemas,
359
+ router: 1,
360
+ maxFrameBytes: 2048,
361
+ writeFrame,
362
+ readFrame: () => Promise.resolve(response),
363
+ });
364
+
365
+ await expect(session.call('Ping', { message: 'x'.repeat(2048) })).rejects.toThrow(
366
+ 'Protocol V2 frame too large for transport: 2061 > 2048'
367
+ );
368
+ expect(writeFrame).not.toHaveBeenCalled();
369
+ });
370
+
272
371
  test('session starts response timeout after the frame is written', async () => {
273
372
  const response = ProtocolV2.encodeFrame(schemas, 'Success', {
274
373
  message: 'ok',
@@ -294,10 +393,9 @@ describe('Protocol V2 framing and session', () => {
294
393
  });
295
394
 
296
395
  test('session accepts response frames with a device-owned seq', async () => {
297
- const response = ProtocolV2.encodeFrame(schemas, 'ProtoVersion', {
298
- major_version: 2,
299
- minor_version: 0,
300
- patch_version: 1,
396
+ const response = ProtocolV2.encodeFrame(schemas, 'ProtocolInfo', {
397
+ version: 2,
398
+ supported_messages: [],
301
399
  });
302
400
  const logger = {
303
401
  debug: jest.fn(),
@@ -310,12 +408,12 @@ describe('Protocol V2 framing and session', () => {
310
408
  logger,
311
409
  });
312
410
 
313
- await expect(session.call('GetProtoVersion', {})).resolves.toEqual({
314
- type: 'ProtoVersion',
411
+ await expect(session.call('ProtocolInfoRequest', {})).resolves.toEqual({
412
+ type: 'ProtocolInfo',
315
413
  message: {
316
- major_version: 2,
317
- minor_version: 0,
318
- patch_version: 1,
414
+ version: 2,
415
+ supported_messages: [],
416
+ protobuf_definition: null,
319
417
  },
320
418
  });
321
419
  expect(logger.debug).toHaveBeenCalledWith(expect.stringContaining('seq differs'));
@@ -399,10 +497,9 @@ describe('Protocol V2 framing and session', () => {
399
497
  const stale = ProtocolV2.encodeFrame(schemas, 'Success', {
400
498
  message: 'stale response',
401
499
  });
402
- const response = ProtocolV2.encodeFrame(schemas, 'ProtoVersion', {
403
- major_version: 2,
404
- minor_version: 0,
405
- patch_version: 1,
500
+ const response = ProtocolV2.encodeFrame(schemas, 'ProtocolInfo', {
501
+ version: 2,
502
+ supported_messages: [],
406
503
  });
407
504
  const logger = {
408
505
  debug: jest.fn(),
@@ -417,13 +514,13 @@ describe('Protocol V2 framing and session', () => {
417
514
  });
418
515
 
419
516
  await expect(
420
- session.call('GetProtoVersion', {}, { expectedTypes: ['ProtoVersion'] })
517
+ session.call('ProtocolInfoRequest', {}, { expectedTypes: ['ProtocolInfo'] })
421
518
  ).resolves.toEqual({
422
- type: 'ProtoVersion',
519
+ type: 'ProtocolInfo',
423
520
  message: {
424
- major_version: 2,
425
- minor_version: 0,
426
- patch_version: 1,
521
+ version: 2,
522
+ supported_messages: [],
523
+ protobuf_definition: null,
427
524
  },
428
525
  });
429
526
 
@@ -433,9 +530,8 @@ describe('Protocol V2 framing and session', () => {
433
530
 
434
531
  test('session consumes intermediate response frames before returning the final response', async () => {
435
532
  const written = [];
436
- const progress = ProtocolV2.encodeFrame(schemas, 'DevFirmwareInstallProgress', {
437
- target_id: 0,
438
- progress: 42,
533
+ const progress = ProtocolV2.encodeFrame(schemas, 'DeviceFirmwareUpdateStatus', {
534
+ records: [{ target_id: 4, status: 1 }],
439
535
  });
440
536
  const success = ProtocolV2.encodeFrame(schemas, 'Success', {
441
537
  message: 'ok',
@@ -459,20 +555,19 @@ describe('Protocol V2 framing and session', () => {
459
555
  });
460
556
 
461
557
  const result = await session.call(
462
- 'DevFirmwareUpdate',
463
- {},
558
+ 'DeviceFirmwareUpdateRequest',
559
+ { targets: [{ target_id: 4, path: 'vol1:firmware.bin' }] },
464
560
  {
465
- intermediateTypes: ['DevFirmwareInstallProgress'],
561
+ intermediateTypes: ['DeviceFirmwareUpdateStatus'],
466
562
  onIntermediateResponse,
467
563
  }
468
564
  );
469
565
 
470
566
  expect(readFrame).toHaveBeenCalledTimes(2);
471
567
  expect(onIntermediateResponse).toHaveBeenCalledWith({
472
- type: 'DevFirmwareInstallProgress',
568
+ type: 'DeviceFirmwareUpdateStatus',
473
569
  message: {
474
- target_id: 0,
475
- progress: 42,
570
+ records: [{ target_id: 4, status: 1, payload_version: null, path: null }],
476
571
  },
477
572
  });
478
573
  expect(result).toEqual({
@@ -483,7 +578,7 @@ describe('Protocol V2 framing and session', () => {
483
578
  });
484
579
  });
485
580
 
486
- test('probeProtocolV2 accepts Ping success as a normal V2 probe response', async () => {
581
+ test('probeProtocolV2 accepts Success as a normal V2 probe response', async () => {
487
582
  await expect(
488
583
  probeProtocolV2({
489
584
  call: () => Promise.resolve({ type: 'Success', message: {} }),
@@ -562,7 +657,7 @@ describe('Protocol V2 framing and session', () => {
562
657
  });
563
658
 
564
659
  await expect(
565
- session.call('GetProtoVersion', {}, { timeoutMs: 10, expectedTypes: ['ProtoVersion'] })
660
+ session.call('ProtocolInfoRequest', {}, { timeoutMs: 10, expectedTypes: ['ProtocolInfo'] })
566
661
  ).rejects.toThrow('Protocol V2 response timeout');
567
662
 
568
663
  // Without cancellation the loop would skip this unexpected Success frame
@@ -661,6 +756,61 @@ describe('Protocol V2 framing and session', () => {
661
756
  expect(written.map(frame => frame[6])).toEqual([1, 2, 1]);
662
757
  });
663
758
 
759
+ test('session reuses an injected sequence cursor across recreated sessions', async () => {
760
+ const written = [];
761
+ const cursor = new ProtocolV2SequenceCursor();
762
+ const makeSession = () =>
763
+ new ProtocolV2Session({
764
+ schemas,
765
+ router: 1,
766
+ sequenceCursor: cursor,
767
+ writeFrame: frame => {
768
+ written.push(frame);
769
+ return Promise.resolve();
770
+ },
771
+ readFrame: () => {
772
+ const [frame] = written.slice(-1);
773
+ const { seq } = protocolV2.decodeFrame(frame);
774
+ return Promise.resolve(
775
+ rewriteSeq(ProtocolV2.encodeFrame(schemas, 'Success', { message: 'ok' }), seq)
776
+ );
777
+ },
778
+ });
779
+
780
+ await makeSession().call('Ping', { message: '1' });
781
+ await makeSession().call('Ping', { message: '2' });
782
+
783
+ expect(written.map(frame => frame[6])).toEqual([1, 2]);
784
+ });
785
+
786
+ test('session passes per-call context to frame IO callbacks', async () => {
787
+ const writeContexts = [];
788
+ const readContexts = [];
789
+ const response = ProtocolV2.encodeFrame(schemas, 'Success', { message: 'ok' });
790
+ const session = new ProtocolV2Session({
791
+ schemas,
792
+ router: 1,
793
+ generation: 7,
794
+ writeFrame: (_frame, context) => {
795
+ writeContexts.push(context);
796
+ return Promise.resolve();
797
+ },
798
+ readFrame: context => {
799
+ readContexts.push(context);
800
+ return Promise.resolve(response);
801
+ },
802
+ });
803
+
804
+ await session.call('Ping', { message: 'ping' }, { timeoutMs: 123 });
805
+ await session.call('FileWrite', {}, { timeoutMs: 456 });
806
+
807
+ expect(writeContexts).toEqual([
808
+ { messageName: 'Ping', timeoutMs: 123, highVolume: false, generation: 7 },
809
+ { messageName: 'FileWrite', timeoutMs: 456, highVolume: true, generation: 7 },
810
+ ]);
811
+ expect(readContexts).toEqual(writeContexts);
812
+ });
813
+
664
814
  test('assembler throws and resets on frames with an impossible length field', () => {
665
815
  const assembler = new ProtocolV2FrameAssembler();
666
816
  // expectedLen = 0 < 8-byte minimum: without the guard this poisons the
@@ -687,10 +837,9 @@ describe('Protocol V2 framing and session', () => {
687
837
  });
688
838
 
689
839
  test('assembler drain returns every buffered complete frame', () => {
690
- const first = ProtocolV2.encodeFrame(schemas, 'ProtoVersion', {
691
- major_version: 1,
692
- minor_version: 0,
693
- patch_version: 0,
840
+ const first = ProtocolV2.encodeFrame(schemas, 'ProtocolInfo', {
841
+ version: 1,
842
+ supported_messages: [],
694
843
  });
695
844
  const second = ProtocolV2.encodeFrame(schemas, 'Success', { message: 'ok' });
696
845
  const third = ProtocolV2.encodeFrame(schemas, 'Success', { message: 'last' });
@@ -714,6 +863,26 @@ describe('Protocol V2 framing and session', () => {
714
863
  expect(decoded.type).toBe('ButtonRequest');
715
864
  });
716
865
 
866
+ test('decodes legacy V1 Failure as a Protocol V2 fallback', () => {
867
+ // Some device-side rejection paths still return legacy Failure(type=3)
868
+ // inside a Protocol V2 frame. It must surface as a device Failure, not as
869
+ // a protobuf catalog TypeError.
870
+ const frame = ProtocolV2.encodeFrame(
871
+ { ...schemas, protocolV2: schemas.protocolV1 },
872
+ 'Failure',
873
+ {
874
+ code: 1,
875
+ message: 'Action cancelled',
876
+ }
877
+ );
878
+ const decoded = ProtocolV2.decodeFrame(schemas, frame);
879
+ expect(decoded.type).toBe('Failure');
880
+ expect(decoded.message).toEqual({
881
+ code: 1,
882
+ message: 'Action cancelled',
883
+ });
884
+ });
885
+
717
886
  test('does not fall back to legacy V1 messages outside the allowlist', () => {
718
887
  // OnekeyFeatures exists only in the V1 schema and is not allowlisted.
719
888
  const frame = protocolV2.encodeProtobufFrame(10026, new Uint8Array(0));
@@ -721,7 +890,6 @@ describe('Protocol V2 framing and session', () => {
721
890
  });
722
891
 
723
892
  test('hexToBytes converts valid hex and rejects malformed input', () => {
724
- const { hexToBytes } = sessionModule;
725
893
  expect(hexToBytes('5a0102')).toEqual(new Uint8Array([0x5a, 0x01, 0x02]));
726
894
  expect(hexToBytes('')).toEqual(new Uint8Array(0));
727
895
  expect(() => hexToBytes('abc')).toThrow('Invalid hex string: odd length');
@@ -729,7 +897,7 @@ describe('Protocol V2 framing and session', () => {
729
897
  });
730
898
 
731
899
  test('probeProtocolV2 only uses Ping for acquire probing', async () => {
732
- const call = jest.fn().mockRejectedValue(new Error('ping timeout'));
900
+ const call = jest.fn().mockRejectedValue(new Error('Ping timeout'));
733
901
  const onProbeFailed = jest.fn();
734
902
 
735
903
  await expect(
@@ -742,7 +910,7 @@ describe('Protocol V2 framing and session', () => {
742
910
  expect(call).toHaveBeenNthCalledWith(
743
911
  1,
744
912
  'Ping',
745
- { message: 'probe' },
913
+ { message: 'protocol-v2-probe' },
746
914
  {
747
915
  timeoutMs: 1,
748
916
  expectedTypes: ['Success'],
@@ -5,9 +5,11 @@ export declare const PROTOCOL_V1_USB_PACKET_SIZE: number;
5
5
  export declare const PROTOCOL_V1_MESSAGE_HEADER_SIZE: number;
6
6
  export declare const PROTOCOL_V1_ENVELOPE_HEADER_SIZE: number;
7
7
  export declare const PROTOCOL_V2_FRAME_MAX_BYTES = 4608;
8
- export declare const PROTOCOL_V2_WEBUSB_FILE_CHUNK_SIZE = 4096;
8
+ export declare const PROTOCOL_V2_WEBUSB_FILE_CHUNK_SIZE = 4000;
9
9
  export declare const PROTOCOL_V2_BLE_FILE_CHUNK_SIZE = 1800;
10
- export declare const PROTOCOL_V2_FILE_CHUNK_SIZE = 4096;
10
+ export declare const PROTOCOL_V2_BLE_FILE_READ_CHUNK_SIZE = 900;
11
+ export declare const PROTOCOL_V2_BLE_FRAME_MAX_BYTES = 2048;
12
+ export declare const PROTOCOL_V2_FILE_CHUNK_SIZE = 4000;
11
13
  export declare const PROTOCOL_V2_CHANNEL_USB = 0;
12
14
  export declare const PROTOCOL_V2_CHANNEL_BLE_UART = 1;
13
15
  export declare const PROTOCOL_V2_CHANNEL_SOCKET = 2;
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,qBAAqB,KAAO,CAAC;AAG1C,eAAO,MAAM,uBAAuB,KAAO,CAAC;AAG5C,eAAO,MAAM,8BAA8B,KAAK,CAAC;AAGjD,eAAO,MAAM,2BAA2B,QAAqC,CAAC;AAG9E,eAAO,MAAM,+BAA+B,QAAQ,CAAC;AAGrD,eAAO,MAAM,gCAAgC,QAA0C,CAAC;AAKxF,eAAO,MAAM,2BAA2B,OAAO,CAAC;AAGhD,eAAO,MAAM,kCAAkC,OAAO,CAAC;AAGvD,eAAO,MAAM,+BAA+B,OAAO,CAAC;AAGpD,eAAO,MAAM,2BAA2B,OAAqC,CAAC;AAM9E,eAAO,MAAM,uBAAuB,IAAI,CAAC;AACzC,eAAO,MAAM,4BAA4B,IAAI,CAAC;AAC9C,eAAO,MAAM,0BAA0B,IAAI,CAAC;AAG5C,eAAO,MAAM,8BAA8B,IAAI,CAAC"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,qBAAqB,KAAO,CAAC;AAG1C,eAAO,MAAM,uBAAuB,KAAO,CAAC;AAG5C,eAAO,MAAM,8BAA8B,KAAK,CAAC;AAGjD,eAAO,MAAM,2BAA2B,QAAqC,CAAC;AAG9E,eAAO,MAAM,+BAA+B,QAAQ,CAAC;AAGrD,eAAO,MAAM,gCAAgC,QAA0C,CAAC;AAKxF,eAAO,MAAM,2BAA2B,OAAO,CAAC;AAGhD,eAAO,MAAM,kCAAkC,OAAO,CAAC;AAGvD,eAAO,MAAM,+BAA+B,OAAO,CAAC;AAGpD,eAAO,MAAM,oCAAoC,MAAM,CAAC;AAGxD,eAAO,MAAM,+BAA+B,OAAO,CAAC;AAGpD,eAAO,MAAM,2BAA2B,OAAqC,CAAC;AAM9E,eAAO,MAAM,uBAAuB,IAAI,CAAC;AACzC,eAAO,MAAM,4BAA4B,IAAI,CAAC;AAC9C,eAAO,MAAM,0BAA0B,IAAI,CAAC;AAG5C,eAAO,MAAM,8BAA8B,IAAI,CAAC"}