@onekeyfe/hd-transport 1.2.0-alpha.21 → 1.2.0-alpha.22
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/__tests__/messages.test.js +32 -7
- package/__tests__/protocol-v2-link-manager.test.js +27 -9
- package/__tests__/protocol-v2.test.js +226 -28
- package/dist/constants.d.ts +1 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/index.d.ts +100 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +157 -58
- package/dist/protocols/index.d.ts +5 -1
- package/dist/protocols/index.d.ts.map +1 -1
- package/dist/protocols/v2/decode.d.ts +11 -0
- package/dist/protocols/v2/decode.d.ts.map +1 -1
- package/dist/protocols/v2/errors.d.ts +8 -0
- package/dist/protocols/v2/errors.d.ts.map +1 -0
- package/dist/protocols/v2/frame-assembler.d.ts.map +1 -1
- package/dist/protocols/v2/index.d.ts +1 -0
- package/dist/protocols/v2/index.d.ts.map +1 -1
- package/dist/protocols/v2/session.d.ts +4 -1
- package/dist/protocols/v2/session.d.ts.map +1 -1
- package/dist/types/messages.d.ts +33 -4
- package/dist/types/messages.d.ts.map +1 -1
- package/messages-protocol-v2.json +77 -4
- package/package.json +2 -2
- package/scripts/protobuf-types.js +7 -1
- package/src/constants.ts +8 -0
- package/src/protocols/index.ts +11 -2
- package/src/protocols/v2/decode.ts +49 -12
- package/src/protocols/v2/errors.ts +23 -0
- package/src/protocols/v2/frame-assembler.ts +6 -4
- package/src/protocols/v2/index.ts +1 -0
- package/src/protocols/v2/session.ts +125 -68
- package/src/types/messages.ts +45 -5
|
@@ -101,17 +101,44 @@ describe('messages', () => {
|
|
|
101
101
|
expect(v2Messages.nested.MessageType.values).toMatchObject({
|
|
102
102
|
MessageType_DeviceStatusGet: 60602,
|
|
103
103
|
MessageType_DeviceStatus: 60603,
|
|
104
|
-
MessageType_DeviceSessionGet: 60606,
|
|
105
104
|
MessageType_DeviceSession: 60607,
|
|
106
105
|
MessageType_DeviceSessionAskPin: 60608,
|
|
106
|
+
MessageType_DeviceSessionOpen: 60609,
|
|
107
107
|
});
|
|
108
108
|
expect(v2Messages.nested.DeviceStatusGet).toEqual({ fields: {} });
|
|
109
|
-
expect(v2Messages.nested.
|
|
109
|
+
expect(v2Messages.nested.ProtocolInfoRequest.fields.eventless_wallet_session).toMatchObject({
|
|
110
|
+
id: 1,
|
|
111
|
+
type: 'bool',
|
|
112
|
+
options: { default: false },
|
|
113
|
+
});
|
|
114
|
+
expect(v2Messages.nested).not.toHaveProperty('DeviceSessionGet');
|
|
115
|
+
expect(v2Messages.nested.DeviceSessionResume.fields.session_id).toMatchObject({
|
|
116
|
+
rule: 'required',
|
|
110
117
|
id: 1,
|
|
111
118
|
type: 'bytes',
|
|
112
119
|
});
|
|
113
|
-
expect(v2Messages.nested).
|
|
114
|
-
|
|
120
|
+
expect(v2Messages.nested.DeviceSessionOpen.fields).toMatchObject({
|
|
121
|
+
resume: { id: 1, type: 'DeviceSessionResume' },
|
|
122
|
+
select: { id: 2, type: 'DeviceSessionSelect' },
|
|
123
|
+
});
|
|
124
|
+
expect(v2Messages.nested.DeviceSessionSelect.fields).toMatchObject({
|
|
125
|
+
host_passphrase: { id: 1, type: 'DeviceSessionHostPassphrase' },
|
|
126
|
+
passphrase_on_device: { id: 2, type: 'DeviceSessionPassphraseOnDevice' },
|
|
127
|
+
attach_pin_on_device: { id: 3, type: 'DeviceSessionAttachPinOnDevice' },
|
|
128
|
+
});
|
|
129
|
+
expect(v2Messages.nested.DeviceSessionHostPassphrase.fields.passphrase).toMatchObject({
|
|
130
|
+
rule: 'required',
|
|
131
|
+
id: 1,
|
|
132
|
+
type: 'string',
|
|
133
|
+
});
|
|
134
|
+
expect(v2Messages.nested.DeviceSessionErrorCode.values).toEqual({
|
|
135
|
+
DeviceSessionError_None: 0,
|
|
136
|
+
DeviceSessionError_UserCancelled: 1,
|
|
137
|
+
DeviceSessionError_InvalidSession: 2,
|
|
138
|
+
DeviceSessionError_AttachPinUnavailable: 3,
|
|
139
|
+
DeviceSessionError_PassphraseDisabled: 4,
|
|
140
|
+
DeviceSessionError_Busy: 5,
|
|
141
|
+
});
|
|
115
142
|
expect(v2Messages.nested).not.toHaveProperty('DeviceWalletSelect');
|
|
116
143
|
expect(v2Messages.nested).not.toHaveProperty('DeviceWalletType');
|
|
117
144
|
expect(v2Messages.nested).not.toHaveProperty('DeviceHiddenWalletSelect');
|
|
@@ -126,9 +153,7 @@ describe('messages', () => {
|
|
|
126
153
|
expect(v2Messages.nested.MessageType.values).not.toHaveProperty(
|
|
127
154
|
'MessageType_DeviceSessionPinResult'
|
|
128
155
|
);
|
|
129
|
-
expect(v2Messages.nested.MessageType.values).not.toHaveProperty(
|
|
130
|
-
'MessageType_DeviceSessionOpen'
|
|
131
|
-
);
|
|
156
|
+
expect(v2Messages.nested.MessageType.values).not.toHaveProperty('MessageType_DeviceSessionGet');
|
|
132
157
|
});
|
|
133
158
|
|
|
134
159
|
test('Protocol V2 onboarding status matches the current firmware-pro2 schema', () => {
|
|
@@ -55,7 +55,12 @@ const rewriteSeq = (frame, seq) => {
|
|
|
55
55
|
const createAdapterFactory = sentSeqs => {
|
|
56
56
|
const adapters = [];
|
|
57
57
|
let generation = 0;
|
|
58
|
-
const success = ProtocolV2.encodeFrame(
|
|
58
|
+
const success = ProtocolV2.encodeFrame(
|
|
59
|
+
schemas,
|
|
60
|
+
'Success',
|
|
61
|
+
{ message: 'ok' },
|
|
62
|
+
{ router: 1, packetSrc: 0, seq: 1 }
|
|
63
|
+
);
|
|
59
64
|
|
|
60
65
|
return {
|
|
61
66
|
adapters,
|
|
@@ -108,12 +113,15 @@ describe('ProtocolV2LinkManager', () => {
|
|
|
108
113
|
|
|
109
114
|
await manager.call('device-a', createAdapter, 'Ping', { message: '1' }, { timeoutMs: 123 });
|
|
110
115
|
|
|
111
|
-
expect(adapters[0].prepareCall).toHaveBeenCalledWith(
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
116
|
+
expect(adapters[0].prepareCall).toHaveBeenCalledWith(
|
|
117
|
+
expect.objectContaining({
|
|
118
|
+
messageName: 'Ping',
|
|
119
|
+
timeoutMs: 123,
|
|
120
|
+
highVolume: false,
|
|
121
|
+
generation: 1,
|
|
122
|
+
signal: expect.any(AbortSignal),
|
|
123
|
+
})
|
|
124
|
+
);
|
|
117
125
|
});
|
|
118
126
|
|
|
119
127
|
test('invalidates a link-fatal call before the next call creates a new link', async () => {
|
|
@@ -200,7 +208,12 @@ describe('ProtocolV2LinkManager', () => {
|
|
|
200
208
|
const deviceABlocked = new Promise(resolve => {
|
|
201
209
|
releaseDeviceA = resolve;
|
|
202
210
|
});
|
|
203
|
-
const success = ProtocolV2.encodeFrame(
|
|
211
|
+
const success = ProtocolV2.encodeFrame(
|
|
212
|
+
schemas,
|
|
213
|
+
'Success',
|
|
214
|
+
{ message: 'ok' },
|
|
215
|
+
{ router: 1, packetSrc: 0, seq: 1 }
|
|
216
|
+
);
|
|
204
217
|
const createAdapter = key => {
|
|
205
218
|
let requestSeq = 0;
|
|
206
219
|
return {
|
|
@@ -298,7 +311,12 @@ describe('ProtocolV2LinkManager', () => {
|
|
|
298
311
|
const writeBlocked = new Promise(resolve => {
|
|
299
312
|
releaseWrite = resolve;
|
|
300
313
|
});
|
|
301
|
-
const success = ProtocolV2.encodeFrame(
|
|
314
|
+
const success = ProtocolV2.encodeFrame(
|
|
315
|
+
schemas,
|
|
316
|
+
'Success',
|
|
317
|
+
{ message: 'ok' },
|
|
318
|
+
{ router: 1, packetSrc: 0, seq: 1 }
|
|
319
|
+
);
|
|
302
320
|
const adapter = {
|
|
303
321
|
router: 1,
|
|
304
322
|
generation: 1,
|
|
@@ -2,13 +2,17 @@ const { ProtocolV2 } = require('../src/protocols');
|
|
|
2
2
|
const { parseConfigure } = require('../src/serialization/protobuf/messages');
|
|
3
3
|
const {
|
|
4
4
|
ProtocolV2FrameAssembler,
|
|
5
|
+
ProtocolV2LinkError,
|
|
5
6
|
ProtocolV2SequenceCursor,
|
|
6
7
|
ProtocolV2Session,
|
|
7
8
|
hexToBytes,
|
|
8
9
|
probeProtocolV2,
|
|
9
10
|
} = require('../src/protocols/v2/session');
|
|
10
11
|
const protocolV2 = require('../src/protocols/v2');
|
|
11
|
-
const {
|
|
12
|
+
const {
|
|
13
|
+
PROTOCOL_V2_DEFAULT_RESPONSE_TIMEOUT_MS,
|
|
14
|
+
PROTOCOL_V2_FRAME_MAX_BYTES,
|
|
15
|
+
} = require('../src/constants');
|
|
12
16
|
|
|
13
17
|
const protocolV1Messages = parseConfigure({
|
|
14
18
|
nested: {
|
|
@@ -221,6 +225,7 @@ const schemas = {
|
|
|
221
225
|
|
|
222
226
|
const rewriteSeq = (frame, seq) => {
|
|
223
227
|
const copy = new Uint8Array(frame);
|
|
228
|
+
copy[4] = 1;
|
|
224
229
|
copy[6] = seq;
|
|
225
230
|
copy[copy.length - 1] = protocolV2.crc8(copy, copy.length - 1);
|
|
226
231
|
return copy;
|
|
@@ -429,7 +434,7 @@ describe('Protocol V2 framing and session', () => {
|
|
|
429
434
|
logger,
|
|
430
435
|
logPrefix: 'ProtocolV2 Test',
|
|
431
436
|
writeFrame: () => Promise.resolve(),
|
|
432
|
-
readFrame: () => Promise.resolve(response),
|
|
437
|
+
readFrame: () => Promise.resolve(rewriteSeq(response, 1)),
|
|
433
438
|
});
|
|
434
439
|
|
|
435
440
|
await expect(session.call('Ping', { message: 'hello' })).rejects.toThrow();
|
|
@@ -451,7 +456,10 @@ describe('Protocol V2 framing and session', () => {
|
|
|
451
456
|
const response = ProtocolV2.encodeFrame(schemas, 'Success', {
|
|
452
457
|
message: 'ok',
|
|
453
458
|
});
|
|
454
|
-
const readFrame = jest
|
|
459
|
+
const readFrame = jest
|
|
460
|
+
.fn()
|
|
461
|
+
.mockResolvedValueOnce(ack)
|
|
462
|
+
.mockResolvedValueOnce(rewriteSeq(response, 1));
|
|
455
463
|
const session = new ProtocolV2Session({
|
|
456
464
|
schemas,
|
|
457
465
|
router: 1,
|
|
@@ -468,6 +476,96 @@ describe('Protocol V2 framing and session', () => {
|
|
|
468
476
|
expect(readFrame).toHaveBeenCalledTimes(2);
|
|
469
477
|
});
|
|
470
478
|
|
|
479
|
+
test('session accepts a terminal response before an ACK', async () => {
|
|
480
|
+
const response = ProtocolV2.encodeFrame(schemas, 'Success', {
|
|
481
|
+
message: 'ok',
|
|
482
|
+
});
|
|
483
|
+
const session = new ProtocolV2Session({
|
|
484
|
+
schemas,
|
|
485
|
+
router: 1,
|
|
486
|
+
writeFrame: () => Promise.resolve(),
|
|
487
|
+
readFrame: () => Promise.resolve(rewriteSeq(response, 1)),
|
|
488
|
+
});
|
|
489
|
+
|
|
490
|
+
await expect(
|
|
491
|
+
session.call('Ping', { message: 'hello' }, { expectedTypes: ['Success'] })
|
|
492
|
+
).resolves.toEqual({
|
|
493
|
+
type: 'Success',
|
|
494
|
+
message: {
|
|
495
|
+
message: 'ok',
|
|
496
|
+
},
|
|
497
|
+
});
|
|
498
|
+
});
|
|
499
|
+
|
|
500
|
+
test('session uses the unified response timeout before the first ACK', async () => {
|
|
501
|
+
const response = ProtocolV2.encodeFrame(schemas, 'Success', {
|
|
502
|
+
message: 'ok',
|
|
503
|
+
});
|
|
504
|
+
const readFrame = jest.fn(() => Promise.resolve(rewriteSeq(response, 1)));
|
|
505
|
+
const session = new ProtocolV2Session({
|
|
506
|
+
schemas,
|
|
507
|
+
router: 1,
|
|
508
|
+
writeFrame: () => Promise.resolve(),
|
|
509
|
+
readFrame,
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
await expect(
|
|
513
|
+
session.call(
|
|
514
|
+
'Ping',
|
|
515
|
+
{ message: 'hello' },
|
|
516
|
+
{
|
|
517
|
+
timeoutMs: 12_345,
|
|
518
|
+
expectedTypes: ['Success'],
|
|
519
|
+
}
|
|
520
|
+
)
|
|
521
|
+
).resolves.toEqual({
|
|
522
|
+
type: 'Success',
|
|
523
|
+
message: {
|
|
524
|
+
message: 'ok',
|
|
525
|
+
},
|
|
526
|
+
});
|
|
527
|
+
expect(readFrame).toHaveBeenCalledWith(expect.objectContaining({ timeoutMs: 12_345 }));
|
|
528
|
+
});
|
|
529
|
+
|
|
530
|
+
test('session rejects an ACK that belongs to another request sequence', async () => {
|
|
531
|
+
const ack = new Uint8Array(8);
|
|
532
|
+
ack[0] = 0x5a;
|
|
533
|
+
ack[1] = 8;
|
|
534
|
+
ack[4] = 1;
|
|
535
|
+
ack[5] = 1;
|
|
536
|
+
ack[6] = 2;
|
|
537
|
+
ack[3] = protocolV2.crc8(ack, 3);
|
|
538
|
+
ack[7] = protocolV2.crc8(ack, 7);
|
|
539
|
+
const session = new ProtocolV2Session({
|
|
540
|
+
schemas,
|
|
541
|
+
router: 1,
|
|
542
|
+
writeFrame: () => Promise.resolve(),
|
|
543
|
+
readFrame: () => Promise.resolve(ack),
|
|
544
|
+
});
|
|
545
|
+
|
|
546
|
+
await expect(session.call('Ping', { message: 'hello' })).rejects.toEqual(
|
|
547
|
+
expect.objectContaining({
|
|
548
|
+
name: 'ProtocolV2LinkError',
|
|
549
|
+
code: 'ack-sequence',
|
|
550
|
+
message: 'Protocol V2 ACK sequence mismatch: expected 1, got 2',
|
|
551
|
+
})
|
|
552
|
+
);
|
|
553
|
+
});
|
|
554
|
+
|
|
555
|
+
test('session rejects a response from another routing channel', async () => {
|
|
556
|
+
const response = ProtocolV2.encodeFrame(schemas, 'Success', { message: 'wrong route' });
|
|
557
|
+
const session = new ProtocolV2Session({
|
|
558
|
+
schemas,
|
|
559
|
+
router: 1,
|
|
560
|
+
writeFrame: () => Promise.resolve(),
|
|
561
|
+
readFrame: () => Promise.resolve(response),
|
|
562
|
+
});
|
|
563
|
+
|
|
564
|
+
await expect(session.call('Ping', { message: 'hello' })).rejects.toBeInstanceOf(
|
|
565
|
+
ProtocolV2LinkError
|
|
566
|
+
);
|
|
567
|
+
});
|
|
568
|
+
|
|
471
569
|
test('session rejects BLE frames above its configured frame limit before writing', async () => {
|
|
472
570
|
const writeFrame = jest.fn().mockResolvedValue(undefined);
|
|
473
571
|
const response = ProtocolV2.encodeFrame(schemas, 'Success', {
|
|
@@ -478,7 +576,7 @@ describe('Protocol V2 framing and session', () => {
|
|
|
478
576
|
router: 1,
|
|
479
577
|
maxFrameBytes: 2048,
|
|
480
578
|
writeFrame,
|
|
481
|
-
readFrame: () => Promise.resolve(response),
|
|
579
|
+
readFrame: () => Promise.resolve(rewriteSeq(response, 1)),
|
|
482
580
|
});
|
|
483
581
|
|
|
484
582
|
await expect(session.call('Ping', { message: 'x'.repeat(2048) })).rejects.toThrow(
|
|
@@ -487,28 +585,40 @@ describe('Protocol V2 framing and session', () => {
|
|
|
487
585
|
expect(writeFrame).not.toHaveBeenCalled();
|
|
488
586
|
});
|
|
489
587
|
|
|
490
|
-
test('session
|
|
491
|
-
const
|
|
492
|
-
|
|
493
|
-
});
|
|
588
|
+
test('session watchdog covers a write that never settles', async () => {
|
|
589
|
+
const readFrame = jest.fn();
|
|
590
|
+
let writeSignal;
|
|
494
591
|
const session = new ProtocolV2Session({
|
|
495
592
|
schemas,
|
|
496
593
|
router: 1,
|
|
497
|
-
writeFrame: () =>
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
readFrame
|
|
594
|
+
writeFrame: (_frame, context) => {
|
|
595
|
+
writeSignal = context.signal;
|
|
596
|
+
return new Promise(() => {});
|
|
597
|
+
},
|
|
598
|
+
readFrame,
|
|
502
599
|
});
|
|
503
600
|
|
|
504
601
|
await expect(
|
|
505
602
|
session.call('Ping', { message: 'hello' }, { timeoutMs: 10, expectedTypes: ['Success'] })
|
|
506
|
-
).
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
603
|
+
).rejects.toThrow('Protocol V2 response timeout after 10ms for Ping');
|
|
604
|
+
expect(writeSignal.aborted).toBe(true);
|
|
605
|
+
expect(readFrame).not.toHaveBeenCalled();
|
|
606
|
+
});
|
|
607
|
+
|
|
608
|
+
test('session watchdog covers prepareCall before writing', async () => {
|
|
609
|
+
const writeFrame = jest.fn();
|
|
610
|
+
const session = new ProtocolV2Session({
|
|
611
|
+
schemas,
|
|
612
|
+
router: 1,
|
|
613
|
+
prepareCall: () => new Promise(() => {}),
|
|
614
|
+
writeFrame,
|
|
615
|
+
readFrame: jest.fn(),
|
|
511
616
|
});
|
|
617
|
+
|
|
618
|
+
await expect(session.call('Ping', { message: 'hello' }, { timeoutMs: 10 })).rejects.toThrow(
|
|
619
|
+
'Protocol V2 response timeout after 10ms for Ping'
|
|
620
|
+
);
|
|
621
|
+
expect(writeFrame).not.toHaveBeenCalled();
|
|
512
622
|
});
|
|
513
623
|
|
|
514
624
|
test('session logs a device-owned response seq without rejecting the frame', async () => {
|
|
@@ -538,6 +648,41 @@ describe('Protocol V2 framing and session', () => {
|
|
|
538
648
|
expect(logger.debug).not.toHaveBeenCalled();
|
|
539
649
|
});
|
|
540
650
|
|
|
651
|
+
test('session accepts gaps in the firmware-global response sequence', async () => {
|
|
652
|
+
const response = ProtocolV2.encodeFrame(schemas, 'Success', { message: 'ok' });
|
|
653
|
+
const readFrame = jest
|
|
654
|
+
.fn()
|
|
655
|
+
.mockResolvedValueOnce(rewriteSeq(response, 1))
|
|
656
|
+
.mockResolvedValueOnce(rewriteSeq(response, 4));
|
|
657
|
+
const session = new ProtocolV2Session({
|
|
658
|
+
schemas,
|
|
659
|
+
router: 1,
|
|
660
|
+
writeFrame: () => Promise.resolve(),
|
|
661
|
+
readFrame,
|
|
662
|
+
});
|
|
663
|
+
|
|
664
|
+
await session.call('Ping', { message: 'first' });
|
|
665
|
+
await expect(session.call('Ping', { message: 'second' })).resolves.toMatchObject({
|
|
666
|
+
type: 'Success',
|
|
667
|
+
});
|
|
668
|
+
});
|
|
669
|
+
|
|
670
|
+
test('session rejects a duplicate device response sequence', async () => {
|
|
671
|
+
const response = ProtocolV2.encodeFrame(schemas, 'Success', { message: 'ok' });
|
|
672
|
+
const readFrame = jest.fn(() => Promise.resolve(rewriteSeq(response, 7)));
|
|
673
|
+
const session = new ProtocolV2Session({
|
|
674
|
+
schemas,
|
|
675
|
+
router: 1,
|
|
676
|
+
writeFrame: () => Promise.resolve(),
|
|
677
|
+
readFrame,
|
|
678
|
+
});
|
|
679
|
+
|
|
680
|
+
await session.call('Ping', { message: 'first' });
|
|
681
|
+
await expect(session.call('Ping', { message: 'second' })).rejects.toThrow(
|
|
682
|
+
'Protocol V2 duplicate response sequence: 7'
|
|
683
|
+
);
|
|
684
|
+
});
|
|
685
|
+
|
|
541
686
|
test('session does not log transmit or receive payload details', async () => {
|
|
542
687
|
const response = ProtocolV2.encodeFrame(schemas, 'Success', {
|
|
543
688
|
message: 'accepted',
|
|
@@ -549,7 +694,7 @@ describe('Protocol V2 framing and session', () => {
|
|
|
549
694
|
schemas,
|
|
550
695
|
router: 1,
|
|
551
696
|
writeFrame: () => Promise.resolve(),
|
|
552
|
-
readFrame: () => Promise.resolve(response),
|
|
697
|
+
readFrame: () => Promise.resolve(rewriteSeq(response, 1)),
|
|
553
698
|
logger,
|
|
554
699
|
logPrefix: 'ProtocolV2 Test',
|
|
555
700
|
});
|
|
@@ -575,7 +720,7 @@ describe('Protocol V2 framing and session', () => {
|
|
|
575
720
|
schemas,
|
|
576
721
|
router: 1,
|
|
577
722
|
writeFrame: () => Promise.resolve(),
|
|
578
|
-
readFrame: () => Promise.resolve(response),
|
|
723
|
+
readFrame: () => Promise.resolve(rewriteSeq(response, 1)),
|
|
579
724
|
logger,
|
|
580
725
|
});
|
|
581
726
|
|
|
@@ -600,7 +745,10 @@ describe('Protocol V2 framing and session', () => {
|
|
|
600
745
|
const logger = {
|
|
601
746
|
debug: jest.fn(),
|
|
602
747
|
};
|
|
603
|
-
const readFrame = jest
|
|
748
|
+
const readFrame = jest
|
|
749
|
+
.fn()
|
|
750
|
+
.mockResolvedValueOnce(rewriteSeq(stale, 1))
|
|
751
|
+
.mockResolvedValueOnce(rewriteSeq(response, 2));
|
|
604
752
|
const session = new ProtocolV2Session({
|
|
605
753
|
schemas,
|
|
606
754
|
router: 1,
|
|
@@ -637,7 +785,9 @@ describe('Protocol V2 framing and session', () => {
|
|
|
637
785
|
const [writtenFrame] = written;
|
|
638
786
|
const { seq } = protocolV2.decodeFrame(writtenFrame);
|
|
639
787
|
return Promise.resolve(
|
|
640
|
-
readFrame.mock.calls.length === 1
|
|
788
|
+
readFrame.mock.calls.length === 1
|
|
789
|
+
? rewriteSeq(progress, seq)
|
|
790
|
+
: rewriteSeq(success, protocolV2.nextProtoSeq(seq))
|
|
641
791
|
);
|
|
642
792
|
});
|
|
643
793
|
const session = new ProtocolV2Session({
|
|
@@ -814,7 +964,7 @@ describe('Protocol V2 framing and session', () => {
|
|
|
814
964
|
}
|
|
815
965
|
return Promise.resolve();
|
|
816
966
|
},
|
|
817
|
-
readFrame: () => Promise.resolve(response),
|
|
967
|
+
readFrame: () => Promise.resolve(rewriteSeq(response, 1)),
|
|
818
968
|
});
|
|
819
969
|
|
|
820
970
|
await expect(session.call('Ping', { message: '1' })).rejects.toThrow('transport write failed');
|
|
@@ -883,6 +1033,7 @@ describe('Protocol V2 framing and session', () => {
|
|
|
883
1033
|
const writeContexts = [];
|
|
884
1034
|
const readContexts = [];
|
|
885
1035
|
const response = ProtocolV2.encodeFrame(schemas, 'Success', { message: 'ok' });
|
|
1036
|
+
let responseSeq = 0;
|
|
886
1037
|
const session = new ProtocolV2Session({
|
|
887
1038
|
schemas,
|
|
888
1039
|
router: 1,
|
|
@@ -893,18 +1044,65 @@ describe('Protocol V2 framing and session', () => {
|
|
|
893
1044
|
},
|
|
894
1045
|
readFrame: context => {
|
|
895
1046
|
readContexts.push(context);
|
|
896
|
-
|
|
1047
|
+
responseSeq = protocolV2.nextProtoSeq(responseSeq);
|
|
1048
|
+
return Promise.resolve(rewriteSeq(response, responseSeq));
|
|
897
1049
|
},
|
|
898
1050
|
});
|
|
899
1051
|
|
|
900
1052
|
await session.call('Ping', { message: 'ping' }, { timeoutMs: 123 });
|
|
901
1053
|
await session.call('FileWrite', {}, { timeoutMs: 456 });
|
|
1054
|
+
await session.call('Ping', { message: 'default-timeout' });
|
|
902
1055
|
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
1056
|
+
const normalizeContext = ({ signal, ...context }) => ({
|
|
1057
|
+
...context,
|
|
1058
|
+
signalAborted: signal.aborted,
|
|
1059
|
+
});
|
|
1060
|
+
expect(writeContexts.map(normalizeContext)).toEqual([
|
|
1061
|
+
{
|
|
1062
|
+
messageName: 'Ping',
|
|
1063
|
+
timeoutMs: 123,
|
|
1064
|
+
highVolume: false,
|
|
1065
|
+
generation: 7,
|
|
1066
|
+
signalAborted: false,
|
|
1067
|
+
},
|
|
1068
|
+
{
|
|
1069
|
+
messageName: 'FileWrite',
|
|
1070
|
+
timeoutMs: 456,
|
|
1071
|
+
highVolume: true,
|
|
1072
|
+
generation: 7,
|
|
1073
|
+
signalAborted: false,
|
|
1074
|
+
},
|
|
1075
|
+
{
|
|
1076
|
+
messageName: 'Ping',
|
|
1077
|
+
timeoutMs: PROTOCOL_V2_DEFAULT_RESPONSE_TIMEOUT_MS,
|
|
1078
|
+
highVolume: false,
|
|
1079
|
+
generation: 7,
|
|
1080
|
+
signalAborted: false,
|
|
1081
|
+
},
|
|
1082
|
+
]);
|
|
1083
|
+
expect(readContexts.map(normalizeContext)).toEqual([
|
|
1084
|
+
{
|
|
1085
|
+
messageName: 'Ping',
|
|
1086
|
+
timeoutMs: 123,
|
|
1087
|
+
highVolume: false,
|
|
1088
|
+
generation: 7,
|
|
1089
|
+
signalAborted: false,
|
|
1090
|
+
},
|
|
1091
|
+
{
|
|
1092
|
+
messageName: 'FileWrite',
|
|
1093
|
+
timeoutMs: 456,
|
|
1094
|
+
highVolume: true,
|
|
1095
|
+
generation: 7,
|
|
1096
|
+
signalAborted: false,
|
|
1097
|
+
},
|
|
1098
|
+
{
|
|
1099
|
+
messageName: 'Ping',
|
|
1100
|
+
timeoutMs: PROTOCOL_V2_DEFAULT_RESPONSE_TIMEOUT_MS,
|
|
1101
|
+
highVolume: false,
|
|
1102
|
+
generation: 7,
|
|
1103
|
+
signalAborted: false,
|
|
1104
|
+
},
|
|
906
1105
|
]);
|
|
907
|
-
expect(readContexts).toEqual(writeContexts);
|
|
908
1106
|
});
|
|
909
1107
|
|
|
910
1108
|
test('assembler throws and resets on frames with an impossible length field', () => {
|
package/dist/constants.d.ts
CHANGED
|
@@ -14,4 +14,5 @@ export declare const PROTOCOL_V2_CHANNEL_USB = 0;
|
|
|
14
14
|
export declare const PROTOCOL_V2_CHANNEL_BLE_UART = 1;
|
|
15
15
|
export declare const PROTOCOL_V2_CHANNEL_SOCKET = 2;
|
|
16
16
|
export declare const PROTOCOL_V2_PACKET_SRC_COMMAND = 0;
|
|
17
|
+
export declare const PROTOCOL_V2_DEFAULT_RESPONSE_TIMEOUT_MS: number;
|
|
17
18
|
//# sourceMappingURL=constants.d.ts.map
|
package/dist/constants.d.ts.map
CHANGED
|
@@ -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,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"}
|
|
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;AAQhD,eAAO,MAAM,uCAAuC,QAAgB,CAAC"}
|