@onekeyfe/hd-transport 1.1.26 → 1.1.27-alpha.31
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__/build-receive.test.js +6 -8
- package/__tests__/decode-features.test.js +3 -2
- package/__tests__/protocol-v2.test.js +481 -0
- package/dist/constants.d.ts +14 -5
- package/dist/constants.d.ts.map +1 -1
- package/dist/index.d.ts +742 -31
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +637 -74
- package/dist/protocols/index.d.ts +40 -0
- package/dist/protocols/index.d.ts.map +1 -0
- package/dist/protocols/v1/decode.d.ts +11 -0
- package/dist/protocols/v1/decode.d.ts.map +1 -0
- package/dist/protocols/v1/encode.d.ts +11 -0
- package/dist/protocols/v1/encode.d.ts.map +1 -0
- package/dist/protocols/v1/index.d.ts +5 -0
- package/dist/protocols/v1/index.d.ts.map +1 -0
- package/dist/protocols/v1/packets.d.ts +7 -0
- package/dist/protocols/v1/packets.d.ts.map +1 -0
- package/dist/{serialization → protocols/v1}/receive.d.ts +1 -1
- package/dist/protocols/v1/receive.d.ts.map +1 -0
- package/dist/protocols/v2/constants.d.ts +7 -0
- package/dist/protocols/v2/constants.d.ts.map +1 -0
- package/dist/protocols/v2/crc8.d.ts +3 -0
- package/dist/protocols/v2/crc8.d.ts.map +1 -0
- package/dist/protocols/v2/decode.d.ts +7 -0
- package/dist/protocols/v2/decode.d.ts.map +1 -0
- package/dist/protocols/v2/encode.d.ts +3 -0
- package/dist/protocols/v2/encode.d.ts.map +1 -0
- package/dist/protocols/v2/frame-assembler.d.ts +9 -0
- package/dist/protocols/v2/frame-assembler.d.ts.map +1 -0
- package/dist/protocols/v2/index.d.ts +6 -0
- package/dist/protocols/v2/index.d.ts.map +1 -0
- package/dist/protocols/v2/session.d.ts +46 -0
- package/dist/protocols/v2/session.d.ts.map +1 -0
- package/dist/serialization/index.d.ts +6 -3
- package/dist/serialization/index.d.ts.map +1 -1
- package/dist/serialization/protobuf/decode.d.ts.map +1 -1
- package/dist/types/messages.d.ts +349 -2
- package/dist/types/messages.d.ts.map +1 -1
- package/dist/types/transport.d.ts +14 -2
- package/dist/types/transport.d.ts.map +1 -1
- package/dist/utils/logBlockCommand.d.ts.map +1 -1
- package/messages-pro2.json +13106 -0
- package/messages.proto +2 -0
- package/package.json +3 -3
- package/scripts/proto-pro2-sys/messages-pro2-sys.proto +231 -0
- package/scripts/protobuf-build.sh +353 -20
- package/scripts/protobuf-patches/index.js +2 -0
- package/scripts/protobuf-types.js +48 -7
- package/src/constants.ts +42 -6
- package/src/index.ts +39 -11
- package/src/protocols/index.ts +83 -0
- package/src/{serialization/protocol → protocols/v1}/decode.ts +4 -4
- package/src/{serialization/protocol → protocols/v1}/encode.ts +15 -10
- package/src/protocols/v1/index.ts +4 -0
- package/src/protocols/v1/packets.ts +53 -0
- package/src/{serialization → protocols/v1}/receive.ts +5 -5
- package/src/protocols/v2/constants.ts +6 -0
- package/src/protocols/v2/crc8.ts +34 -0
- package/src/protocols/v2/decode.ts +72 -0
- package/src/protocols/v2/encode.ts +75 -0
- package/src/protocols/v2/frame-assembler.ts +51 -0
- package/src/protocols/v2/index.ts +5 -0
- package/src/protocols/v2/session.ts +357 -0
- package/src/serialization/index.ts +6 -5
- package/src/serialization/protobuf/decode.ts +7 -0
- package/src/types/messages.ts +464 -2
- package/src/types/transport.ts +25 -2
- package/src/utils/logBlockCommand.ts +9 -1
- package/dist/serialization/protocol/decode.d.ts +0 -11
- package/dist/serialization/protocol/decode.d.ts.map +0 -1
- package/dist/serialization/protocol/encode.d.ts +0 -11
- package/dist/serialization/protocol/encode.d.ts.map +0 -1
- package/dist/serialization/protocol/index.d.ts +0 -3
- package/dist/serialization/protocol/index.d.ts.map +0 -1
- package/dist/serialization/receive.d.ts.map +0 -1
- package/dist/serialization/send.d.ts +0 -7
- package/dist/serialization/send.d.ts.map +0 -1
- package/src/serialization/protocol/index.ts +0 -2
- package/src/serialization/send.ts +0 -58
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
const { parseConfigure } = require('../src/serialization/protobuf/messages');
|
|
2
|
-
const {
|
|
3
|
-
const { receiveOne } = require('../src/serialization/receive');
|
|
4
|
-
const { buildEncodeBuffers } = require('../src/serialization/send');
|
|
2
|
+
const { ProtocolV1 } = require('../src/protocols');
|
|
5
3
|
|
|
6
4
|
const messages = {
|
|
7
5
|
StellarPaymentOp: {
|
|
@@ -96,17 +94,17 @@ const parsedMessages = parseConfigure({
|
|
|
96
94
|
describe('encoding json -> protobuf -> json', () => {
|
|
97
95
|
fixtures.forEach(f => {
|
|
98
96
|
describe(f.name, () => {
|
|
99
|
-
test('
|
|
97
|
+
test('encodeEnvelope - decodeMessage', () => {
|
|
100
98
|
// encoded message
|
|
101
|
-
const encodedMessage =
|
|
99
|
+
const encodedMessage = ProtocolV1.encodeEnvelope(parsedMessages, f.name, f.in);
|
|
102
100
|
// then decode message and check, whether decoded message matches original json
|
|
103
|
-
const decodedMessage =
|
|
101
|
+
const decodedMessage = ProtocolV1.decodeMessage(parsedMessages, encodedMessage);
|
|
104
102
|
expect(decodedMessage.type).toEqual(f.name);
|
|
105
103
|
expect(decodedMessage.message).toEqual(f.in);
|
|
106
104
|
});
|
|
107
105
|
|
|
108
|
-
test('
|
|
109
|
-
const result =
|
|
106
|
+
test('encodeMessageChunks - receiveAndParse', () => {
|
|
107
|
+
const result = ProtocolV1.encodeMessageChunks(parsedMessages, f.name, f.in);
|
|
110
108
|
result.forEach(r => {
|
|
111
109
|
expect(r.byteLength).toBeLessThanOrEqual(63);
|
|
112
110
|
});
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
/* eslint-disable import/order */
|
|
1
2
|
const ProtoBuf = require('protobufjs/light');
|
|
2
3
|
const ByteBuffer = require('bytebuffer');
|
|
3
4
|
|
|
4
5
|
const { decode } = require('../src/serialization/protobuf/decode');
|
|
5
|
-
const {
|
|
6
|
+
const { decodeEnvelope } = require('../src/protocols/v1/decode');
|
|
6
7
|
|
|
7
8
|
// Reuse the messages.json already committed alongside @onekeyfe/hd-core
|
|
8
9
|
// (runtime data for DataManager). hd-transport's own messages.json is
|
|
@@ -61,7 +62,7 @@ describe('Fix messages decode', () => {
|
|
|
61
62
|
test('decode', () => {
|
|
62
63
|
// deserialize
|
|
63
64
|
const encoded = ByteBuffer.fromHex(f.encodeMessage);
|
|
64
|
-
const { buffer } =
|
|
65
|
+
const { buffer } = decodeEnvelope(encoded);
|
|
65
66
|
const decoded = decode(Message, buffer);
|
|
66
67
|
|
|
67
68
|
// filter null values
|
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
const { ProtocolV2 } = require('../src/protocols');
|
|
2
|
+
const { parseConfigure } = require('../src/serialization/protobuf/messages');
|
|
3
|
+
const {
|
|
4
|
+
ProtocolV2FrameAssembler,
|
|
5
|
+
ProtocolV2Session,
|
|
6
|
+
probeProtocolV2,
|
|
7
|
+
} = require('../src/protocols/v2/session');
|
|
8
|
+
const protocolV2 = require('../src/protocols/v2');
|
|
9
|
+
|
|
10
|
+
const protocolV1Messages = parseConfigure({
|
|
11
|
+
nested: {
|
|
12
|
+
Success: {
|
|
13
|
+
fields: {
|
|
14
|
+
message: {
|
|
15
|
+
type: 'string',
|
|
16
|
+
id: 1,
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
OnekeyGetFeatures: {
|
|
21
|
+
fields: {},
|
|
22
|
+
},
|
|
23
|
+
OnekeyFeatures: {
|
|
24
|
+
fields: {},
|
|
25
|
+
},
|
|
26
|
+
MessageType: {
|
|
27
|
+
values: {
|
|
28
|
+
MessageType_Success: 2,
|
|
29
|
+
MessageType_OnekeyGetFeatures: 10025,
|
|
30
|
+
MessageType_OnekeyFeatures: 10026,
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const protocolV2Messages = parseConfigure({
|
|
37
|
+
nested: {
|
|
38
|
+
GetProtoVersion: {
|
|
39
|
+
fields: {},
|
|
40
|
+
},
|
|
41
|
+
ProtoVersion: {
|
|
42
|
+
fields: {
|
|
43
|
+
major_version: {
|
|
44
|
+
type: 'uint32',
|
|
45
|
+
id: 1,
|
|
46
|
+
},
|
|
47
|
+
minor_version: {
|
|
48
|
+
type: 'uint32',
|
|
49
|
+
id: 2,
|
|
50
|
+
},
|
|
51
|
+
patch_version: {
|
|
52
|
+
type: 'uint32',
|
|
53
|
+
id: 3,
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
Ping: {
|
|
58
|
+
fields: {
|
|
59
|
+
message: {
|
|
60
|
+
type: 'string',
|
|
61
|
+
id: 1,
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
Success: {
|
|
66
|
+
fields: {
|
|
67
|
+
message: {
|
|
68
|
+
type: 'string',
|
|
69
|
+
id: 1,
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
DeviceFirmwareUpdate: {
|
|
74
|
+
fields: {},
|
|
75
|
+
},
|
|
76
|
+
DeviceFirmwareInstallProgress: {
|
|
77
|
+
fields: {
|
|
78
|
+
target_id: {
|
|
79
|
+
type: 'uint32',
|
|
80
|
+
id: 1,
|
|
81
|
+
},
|
|
82
|
+
progress: {
|
|
83
|
+
type: 'uint32',
|
|
84
|
+
id: 2,
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
FileWrite: {
|
|
89
|
+
fields: {},
|
|
90
|
+
},
|
|
91
|
+
PartialNested: {
|
|
92
|
+
fields: {
|
|
93
|
+
child: {
|
|
94
|
+
type: 'NestedChild',
|
|
95
|
+
id: 1,
|
|
96
|
+
},
|
|
97
|
+
label: {
|
|
98
|
+
type: 'string',
|
|
99
|
+
id: 2,
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
NestedChild: {
|
|
104
|
+
fields: {
|
|
105
|
+
value: {
|
|
106
|
+
type: 'string',
|
|
107
|
+
id: 1,
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
MessageType: {
|
|
112
|
+
values: {
|
|
113
|
+
MessageType_GetProtoVersion: 60200,
|
|
114
|
+
MessageType_ProtoVersion: 60201,
|
|
115
|
+
MessageType_Ping: 60206,
|
|
116
|
+
MessageType_Success: 60207,
|
|
117
|
+
MessageType_FileWrite: 60805,
|
|
118
|
+
MessageType_DeviceFirmwareUpdate: 61000,
|
|
119
|
+
MessageType_DeviceFirmwareInstallProgress: 61001,
|
|
120
|
+
MessageType_PartialNested: 62000,
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
const schemas = {
|
|
127
|
+
protocolV1: protocolV1Messages,
|
|
128
|
+
protocolV2: protocolV2Messages,
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
const rewriteSeq = (frame, seq) => {
|
|
132
|
+
const copy = new Uint8Array(frame);
|
|
133
|
+
copy[6] = seq;
|
|
134
|
+
copy[copy.length - 1] = protocolV2.crc8(copy, copy.length - 1);
|
|
135
|
+
return copy;
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
describe('Protocol V2 framing and session', () => {
|
|
139
|
+
test('encodes and decodes Protocol V2 protobuf frames', () => {
|
|
140
|
+
const frame = ProtocolV2.encodeFrame(schemas, 'ProtoVersion', {
|
|
141
|
+
major_version: 1,
|
|
142
|
+
minor_version: 2,
|
|
143
|
+
patch_version: 3,
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
const parsed = protocolV2.decodeFrame(frame);
|
|
147
|
+
expect(parsed.msgType).toBe(60201);
|
|
148
|
+
|
|
149
|
+
const decoded = ProtocolV2.decodeFrame(schemas, frame);
|
|
150
|
+
expect(decoded).toEqual({
|
|
151
|
+
type: 'ProtoVersion',
|
|
152
|
+
messageName: 'ProtoVersion',
|
|
153
|
+
msgType: 60201,
|
|
154
|
+
pbPayload: parsed.pbPayload,
|
|
155
|
+
seq: parsed.seq,
|
|
156
|
+
message: {
|
|
157
|
+
major_version: 1,
|
|
158
|
+
minor_version: 2,
|
|
159
|
+
patch_version: 3,
|
|
160
|
+
},
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
test('does not encode V1-only messages into Protocol V2 frames', () => {
|
|
165
|
+
expect(() => ProtocolV2.encodeFrame(schemas, 'Ping', { message: 'ok' })).not.toThrow();
|
|
166
|
+
expect(() => ProtocolV2.encodeFrame(schemas, 'OnekeyGetFeatures', {})).toThrow(
|
|
167
|
+
'Protocol V2 message "OnekeyGetFeatures" is not defined'
|
|
168
|
+
);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
test('decodes Protocol V2 frames with the Protocol V2 catalog first', () => {
|
|
172
|
+
const frame = ProtocolV2.encodeFrame(schemas, 'Success', {
|
|
173
|
+
message: 'ok',
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
const parsed = protocolV2.decodeFrame(frame);
|
|
177
|
+
expect(parsed.msgType).toBe(60207);
|
|
178
|
+
|
|
179
|
+
const decoded = ProtocolV2.decodeFrame(schemas, frame);
|
|
180
|
+
expect(decoded.type).toBe('Success');
|
|
181
|
+
expect(decoded.message).toEqual({ message: 'ok' });
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
test('decodes missing optional nested messages as null', () => {
|
|
185
|
+
const frame = ProtocolV2.encodeFrame(schemas, 'PartialNested', {
|
|
186
|
+
label: 'only label',
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
const decoded = ProtocolV2.decodeFrame(schemas, frame);
|
|
190
|
+
expect(decoded.message).toEqual({
|
|
191
|
+
child: null,
|
|
192
|
+
label: 'only label',
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
test('reassembles split Protocol V2 frames and rejects oversized frames', () => {
|
|
197
|
+
const frame = ProtocolV2.encodeFrame(schemas, 'ProtoVersion', {
|
|
198
|
+
major_version: 1,
|
|
199
|
+
minor_version: 0,
|
|
200
|
+
patch_version: 0,
|
|
201
|
+
});
|
|
202
|
+
const assembler = new ProtocolV2FrameAssembler();
|
|
203
|
+
|
|
204
|
+
expect(assembler.push(frame.slice(0, 4))).toBeUndefined();
|
|
205
|
+
expect(assembler.push(frame.slice(4))).toEqual(frame);
|
|
206
|
+
|
|
207
|
+
const oversized = new Uint8Array([0x5a, 0xff, 0xff]);
|
|
208
|
+
expect(() => assembler.push(oversized)).toThrow('Protocol V2 frame too large');
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
test('keeps bytes after the first complete frame for the next read', () => {
|
|
212
|
+
const first = ProtocolV2.encodeFrame(schemas, 'ProtoVersion', {
|
|
213
|
+
major_version: 1,
|
|
214
|
+
minor_version: 0,
|
|
215
|
+
patch_version: 0,
|
|
216
|
+
});
|
|
217
|
+
const second = ProtocolV2.encodeFrame(schemas, 'ProtoVersion', {
|
|
218
|
+
major_version: 2,
|
|
219
|
+
minor_version: 0,
|
|
220
|
+
patch_version: 0,
|
|
221
|
+
});
|
|
222
|
+
const assembler = new ProtocolV2FrameAssembler();
|
|
223
|
+
const combined = new Uint8Array(first.length + second.length);
|
|
224
|
+
combined.set(first, 0);
|
|
225
|
+
combined.set(second, first.length);
|
|
226
|
+
|
|
227
|
+
expect(assembler.push(combined)).toEqual(first);
|
|
228
|
+
expect(assembler.push(new Uint8Array(0))).toEqual(second);
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
test('session writes one encoded frame and decodes the response frame', async () => {
|
|
232
|
+
const written = [];
|
|
233
|
+
const response = ProtocolV2.encodeFrame(schemas, 'ProtoVersion', {
|
|
234
|
+
major_version: 2,
|
|
235
|
+
minor_version: 0,
|
|
236
|
+
patch_version: 1,
|
|
237
|
+
});
|
|
238
|
+
const session = new ProtocolV2Session({
|
|
239
|
+
schemas,
|
|
240
|
+
router: 1,
|
|
241
|
+
writeFrame: frame => {
|
|
242
|
+
written.push(frame);
|
|
243
|
+
return Promise.resolve();
|
|
244
|
+
},
|
|
245
|
+
readFrame: () =>
|
|
246
|
+
Promise.resolve(rewriteSeq(response, protocolV2.decodeFrame(written[0]).seq)),
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
const result = await session.call('GetProtoVersion', {});
|
|
250
|
+
|
|
251
|
+
expect(written).toHaveLength(1);
|
|
252
|
+
expect(written[0][4]).toBe(1);
|
|
253
|
+
expect(written[0][5]).toBe(0);
|
|
254
|
+
expect(protocolV2.decodeFrame(written[0]).msgType).toBe(60200);
|
|
255
|
+
expect(result).toEqual({
|
|
256
|
+
type: 'ProtoVersion',
|
|
257
|
+
message: {
|
|
258
|
+
major_version: 2,
|
|
259
|
+
minor_version: 0,
|
|
260
|
+
patch_version: 1,
|
|
261
|
+
},
|
|
262
|
+
});
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
test('session accepts response frames with a device-owned seq', async () => {
|
|
266
|
+
const response = ProtocolV2.encodeFrame(schemas, 'ProtoVersion', {
|
|
267
|
+
major_version: 2,
|
|
268
|
+
minor_version: 0,
|
|
269
|
+
patch_version: 1,
|
|
270
|
+
});
|
|
271
|
+
const logger = {
|
|
272
|
+
debug: jest.fn(),
|
|
273
|
+
};
|
|
274
|
+
const session = new ProtocolV2Session({
|
|
275
|
+
schemas,
|
|
276
|
+
router: 1,
|
|
277
|
+
writeFrame: () => Promise.resolve(),
|
|
278
|
+
readFrame: () => Promise.resolve(response),
|
|
279
|
+
logger,
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
await expect(session.call('GetProtoVersion', {})).resolves.toEqual({
|
|
283
|
+
type: 'ProtoVersion',
|
|
284
|
+
message: {
|
|
285
|
+
major_version: 2,
|
|
286
|
+
minor_version: 0,
|
|
287
|
+
patch_version: 1,
|
|
288
|
+
},
|
|
289
|
+
});
|
|
290
|
+
expect(logger.debug).toHaveBeenCalledWith(expect.stringContaining('seq differs'));
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
test('session logs decoded transmit and receive payloads', async () => {
|
|
294
|
+
const response = ProtocolV2.encodeFrame(schemas, 'Success', {
|
|
295
|
+
message: 'accepted',
|
|
296
|
+
});
|
|
297
|
+
const logger = {
|
|
298
|
+
debug: jest.fn(),
|
|
299
|
+
};
|
|
300
|
+
const session = new ProtocolV2Session({
|
|
301
|
+
schemas,
|
|
302
|
+
router: 1,
|
|
303
|
+
writeFrame: () => Promise.resolve(),
|
|
304
|
+
readFrame: () => Promise.resolve(response),
|
|
305
|
+
logger,
|
|
306
|
+
logPrefix: 'ProtocolV2 Test',
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
await expect(session.call('Ping', { message: 'hello' })).resolves.toEqual({
|
|
310
|
+
type: 'Success',
|
|
311
|
+
message: {
|
|
312
|
+
message: 'accepted',
|
|
313
|
+
},
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
expect(logger.debug).toHaveBeenCalledWith('[ProtocolV2 Test] TX payload name=Ping', {
|
|
317
|
+
message: 'hello',
|
|
318
|
+
});
|
|
319
|
+
expect(logger.debug).toHaveBeenCalledWith(
|
|
320
|
+
'[ProtocolV2 Test] RX payload type=Success msgType=60207',
|
|
321
|
+
{
|
|
322
|
+
message: 'accepted',
|
|
323
|
+
}
|
|
324
|
+
);
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
test('session suppresses payload logs for file transfer calls', async () => {
|
|
328
|
+
const response = ProtocolV2.encodeFrame(schemas, 'Success', {
|
|
329
|
+
message: 'ok',
|
|
330
|
+
});
|
|
331
|
+
const logger = {
|
|
332
|
+
debug: jest.fn(),
|
|
333
|
+
};
|
|
334
|
+
const session = new ProtocolV2Session({
|
|
335
|
+
schemas,
|
|
336
|
+
router: 1,
|
|
337
|
+
writeFrame: () => Promise.resolve(),
|
|
338
|
+
readFrame: () => Promise.resolve(response),
|
|
339
|
+
logger,
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
await expect(session.call('FileWrite', {})).resolves.toEqual({
|
|
343
|
+
type: 'Success',
|
|
344
|
+
message: {
|
|
345
|
+
message: 'ok',
|
|
346
|
+
},
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
expect(logger.debug.mock.calls.some(([message]) => String(message).includes('payload'))).toBe(
|
|
350
|
+
false
|
|
351
|
+
);
|
|
352
|
+
});
|
|
353
|
+
|
|
354
|
+
test('session skips unrelated terminal frames when expected response types are provided', async () => {
|
|
355
|
+
const stale = ProtocolV2.encodeFrame(schemas, 'Success', {
|
|
356
|
+
message: 'stale response',
|
|
357
|
+
});
|
|
358
|
+
const response = ProtocolV2.encodeFrame(schemas, 'ProtoVersion', {
|
|
359
|
+
major_version: 2,
|
|
360
|
+
minor_version: 0,
|
|
361
|
+
patch_version: 1,
|
|
362
|
+
});
|
|
363
|
+
const logger = {
|
|
364
|
+
debug: jest.fn(),
|
|
365
|
+
};
|
|
366
|
+
const readFrame = jest.fn().mockResolvedValueOnce(stale).mockResolvedValueOnce(response);
|
|
367
|
+
const session = new ProtocolV2Session({
|
|
368
|
+
schemas,
|
|
369
|
+
router: 1,
|
|
370
|
+
writeFrame: () => Promise.resolve(),
|
|
371
|
+
readFrame,
|
|
372
|
+
logger,
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
await expect(
|
|
376
|
+
session.call('GetProtoVersion', {}, { expectedTypes: ['ProtoVersion'] })
|
|
377
|
+
).resolves.toEqual({
|
|
378
|
+
type: 'ProtoVersion',
|
|
379
|
+
message: {
|
|
380
|
+
major_version: 2,
|
|
381
|
+
minor_version: 0,
|
|
382
|
+
patch_version: 1,
|
|
383
|
+
},
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
expect(readFrame).toHaveBeenCalledTimes(2);
|
|
387
|
+
expect(logger.debug).toHaveBeenCalledWith(expect.stringContaining('skip unexpected response'));
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
test('session consumes intermediate response frames before returning the final response', async () => {
|
|
391
|
+
const written = [];
|
|
392
|
+
const progress = ProtocolV2.encodeFrame(schemas, 'DeviceFirmwareInstallProgress', {
|
|
393
|
+
target_id: 0,
|
|
394
|
+
progress: 42,
|
|
395
|
+
});
|
|
396
|
+
const success = ProtocolV2.encodeFrame(schemas, 'Success', {
|
|
397
|
+
message: 'ok',
|
|
398
|
+
});
|
|
399
|
+
const onIntermediateResponse = jest.fn();
|
|
400
|
+
const readFrame = jest.fn(() => {
|
|
401
|
+
const [writtenFrame] = written;
|
|
402
|
+
const { seq } = protocolV2.decodeFrame(writtenFrame);
|
|
403
|
+
return Promise.resolve(
|
|
404
|
+
readFrame.mock.calls.length === 1 ? rewriteSeq(progress, seq) : rewriteSeq(success, seq)
|
|
405
|
+
);
|
|
406
|
+
});
|
|
407
|
+
const session = new ProtocolV2Session({
|
|
408
|
+
schemas,
|
|
409
|
+
router: 1,
|
|
410
|
+
writeFrame: frame => {
|
|
411
|
+
written.push(frame);
|
|
412
|
+
return Promise.resolve();
|
|
413
|
+
},
|
|
414
|
+
readFrame,
|
|
415
|
+
});
|
|
416
|
+
|
|
417
|
+
const result = await session.call(
|
|
418
|
+
'DeviceFirmwareUpdate',
|
|
419
|
+
{},
|
|
420
|
+
{
|
|
421
|
+
intermediateTypes: ['DeviceFirmwareInstallProgress'],
|
|
422
|
+
onIntermediateResponse,
|
|
423
|
+
}
|
|
424
|
+
);
|
|
425
|
+
|
|
426
|
+
expect(readFrame).toHaveBeenCalledTimes(2);
|
|
427
|
+
expect(onIntermediateResponse).toHaveBeenCalledWith({
|
|
428
|
+
type: 'DeviceFirmwareInstallProgress',
|
|
429
|
+
message: {
|
|
430
|
+
target_id: 0,
|
|
431
|
+
progress: 42,
|
|
432
|
+
},
|
|
433
|
+
});
|
|
434
|
+
expect(result).toEqual({
|
|
435
|
+
type: 'Success',
|
|
436
|
+
message: {
|
|
437
|
+
message: 'ok',
|
|
438
|
+
},
|
|
439
|
+
});
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
test('probeProtocolV2 accepts Ping success as a normal V2 probe response', async () => {
|
|
443
|
+
await expect(
|
|
444
|
+
probeProtocolV2({
|
|
445
|
+
call: () => Promise.resolve({ type: 'Success', message: {} }),
|
|
446
|
+
timeoutMs: 1,
|
|
447
|
+
})
|
|
448
|
+
).resolves.toBe(true);
|
|
449
|
+
|
|
450
|
+
await expect(
|
|
451
|
+
probeProtocolV2({
|
|
452
|
+
call: () => Promise.resolve({ type: 'Failure', message: {} }),
|
|
453
|
+
timeoutMs: 1,
|
|
454
|
+
})
|
|
455
|
+
).resolves.toBe(false);
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
test('probeProtocolV2 only uses Ping for acquire probing', async () => {
|
|
459
|
+
const call = jest.fn().mockRejectedValue(new Error('ping timeout'));
|
|
460
|
+
const onProbeFailed = jest.fn();
|
|
461
|
+
|
|
462
|
+
await expect(
|
|
463
|
+
probeProtocolV2({
|
|
464
|
+
call,
|
|
465
|
+
timeoutMs: 1,
|
|
466
|
+
onProbeFailed,
|
|
467
|
+
})
|
|
468
|
+
).resolves.toBe(false);
|
|
469
|
+
expect(call).toHaveBeenNthCalledWith(
|
|
470
|
+
1,
|
|
471
|
+
'Ping',
|
|
472
|
+
{ message: 'probe' },
|
|
473
|
+
{
|
|
474
|
+
timeoutMs: 1,
|
|
475
|
+
expectedTypes: ['Success'],
|
|
476
|
+
}
|
|
477
|
+
);
|
|
478
|
+
expect(call).toHaveBeenCalledTimes(1);
|
|
479
|
+
expect(onProbeFailed).toHaveBeenCalledWith(expect.any(Error));
|
|
480
|
+
});
|
|
481
|
+
});
|
package/dist/constants.d.ts
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
|
-
export declare const
|
|
2
|
-
export declare const
|
|
3
|
-
export declare const
|
|
4
|
-
export declare const
|
|
5
|
-
export declare const
|
|
1
|
+
export declare const PROTOCOL_V1_REPORT_ID = 63;
|
|
2
|
+
export declare const PROTOCOL_V1_HEADER_BYTE = 35;
|
|
3
|
+
export declare const PROTOCOL_V1_CHUNK_PAYLOAD_SIZE = 63;
|
|
4
|
+
export declare const PROTOCOL_V1_USB_PACKET_SIZE: number;
|
|
5
|
+
export declare const PROTOCOL_V1_MESSAGE_HEADER_SIZE: number;
|
|
6
|
+
export declare const PROTOCOL_V1_ENVELOPE_HEADER_SIZE: number;
|
|
7
|
+
export declare const PROTOCOL_V2_FRAME_MAX_BYTES = 4608;
|
|
8
|
+
export declare const PROTOCOL_V2_WEBUSB_FILE_CHUNK_SIZE = 4096;
|
|
9
|
+
export declare const PROTOCOL_V2_BLE_FILE_CHUNK_SIZE = 1800;
|
|
10
|
+
export declare const PROTOCOL_V2_FILE_CHUNK_SIZE = 4096;
|
|
11
|
+
export declare const PROTOCOL_V2_CHANNEL_USB = 0;
|
|
12
|
+
export declare const PROTOCOL_V2_CHANNEL_BLE_UART = 1;
|
|
13
|
+
export declare const PROTOCOL_V2_CHANNEL_SOCKET = 2;
|
|
14
|
+
export declare const PROTOCOL_V2_PACKET_SRC_COMMAND = 0;
|
|
6
15
|
//# 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":"
|
|
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"}
|