@onekeyfe/hd-transport 1.2.0-alpha.19 → 1.2.0-alpha.20
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 +8 -9
- package/__tests__/protocol-v2-link-manager.test.js +25 -0
- package/__tests__/protocol-v2.test.js +68 -0
- package/dist/constants.d.ts +1 -1
- package/dist/index.d.ts +84 -41
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +55 -8
- package/dist/protocols/index.d.ts +2 -1
- package/dist/protocols/index.d.ts.map +1 -1
- package/dist/protocols/v2/decode.d.ts +1 -0
- package/dist/protocols/v2/decode.d.ts.map +1 -1
- package/dist/protocols/v2/link-manager.d.ts +1 -0
- package/dist/protocols/v2/link-manager.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 +6 -25
- package/dist/types/messages.d.ts.map +1 -1
- package/dist/types/transport.d.ts +1 -1
- package/dist/types/transport.d.ts.map +1 -1
- package/messages-protocol-v2.json +25 -79
- package/package.json +2 -2
- package/src/constants.ts +16 -16
- package/src/protocols/index.ts +7 -1
- package/src/protocols/v2/crc8.ts +1 -1
- package/src/protocols/v2/decode.ts +7 -0
- package/src/protocols/v2/encode.ts +1 -1
- package/src/protocols/v2/link-manager.ts +2 -0
- package/src/protocols/v2/session.ts +57 -16
- package/src/protocols/v2/usb-transport-base.ts +1 -1
- package/src/types/messages.ts +7 -36
- package/src/types/transport.ts +2 -6
|
@@ -482,7 +482,7 @@
|
|
|
482
482
|
"MessageType_DeviceStatus": 60603,
|
|
483
483
|
"MessageType_DevGetOnboardingStatus": 60604,
|
|
484
484
|
"MessageType_DevOnboardingStatus": 60605,
|
|
485
|
-
"
|
|
485
|
+
"MessageType_DeviceSessionGet": 60606,
|
|
486
486
|
"MessageType_DeviceSession": 60607,
|
|
487
487
|
"MessageType_DeviceSessionAskPin": 60608,
|
|
488
488
|
"MessageType_FilesystemPermissionFix": 60800,
|
|
@@ -11849,61 +11849,49 @@
|
|
|
11849
11849
|
},
|
|
11850
11850
|
"DeviceSettings": {
|
|
11851
11851
|
"fields": {
|
|
11852
|
-
"label": {
|
|
11853
|
-
"type": "string",
|
|
11854
|
-
"id": 1
|
|
11855
|
-
},
|
|
11856
11852
|
"bt_enable": {
|
|
11857
11853
|
"type": "bool",
|
|
11858
|
-
"id":
|
|
11854
|
+
"id": 1
|
|
11859
11855
|
},
|
|
11860
11856
|
"language": {
|
|
11861
11857
|
"type": "string",
|
|
11862
|
-
"id":
|
|
11858
|
+
"id": 2
|
|
11863
11859
|
},
|
|
11864
11860
|
"wallpaper_path": {
|
|
11865
11861
|
"type": "string",
|
|
11866
|
-
"id":
|
|
11862
|
+
"id": 3
|
|
11867
11863
|
},
|
|
11868
11864
|
"brightness": {
|
|
11869
11865
|
"type": "uint32",
|
|
11870
|
-
"id":
|
|
11871
|
-
},
|
|
11872
|
-
"autolock_delay_ms": {
|
|
11873
|
-
"type": "uint32",
|
|
11874
|
-
"id": 8
|
|
11875
|
-
},
|
|
11876
|
-
"autoshutdown_delay_ms": {
|
|
11877
|
-
"type": "uint32",
|
|
11878
|
-
"id": 9
|
|
11866
|
+
"id": 4
|
|
11879
11867
|
},
|
|
11880
11868
|
"animation_enable": {
|
|
11881
11869
|
"type": "bool",
|
|
11882
|
-
"id":
|
|
11870
|
+
"id": 5
|
|
11883
11871
|
},
|
|
11884
11872
|
"tap_to_wake": {
|
|
11885
11873
|
"type": "bool",
|
|
11886
|
-
"id":
|
|
11874
|
+
"id": 6
|
|
11887
11875
|
},
|
|
11888
11876
|
"haptic_feedback": {
|
|
11889
11877
|
"type": "bool",
|
|
11890
|
-
"id":
|
|
11878
|
+
"id": 7
|
|
11891
11879
|
},
|
|
11892
11880
|
"device_name_display_enabled": {
|
|
11893
11881
|
"type": "bool",
|
|
11894
|
-
"id":
|
|
11882
|
+
"id": 8
|
|
11895
11883
|
},
|
|
11896
11884
|
"airgap_mode": {
|
|
11897
11885
|
"type": "bool",
|
|
11898
|
-
"id":
|
|
11886
|
+
"id": 9
|
|
11899
11887
|
},
|
|
11900
11888
|
"usb_lock_enable": {
|
|
11901
11889
|
"type": "bool",
|
|
11902
|
-
"id":
|
|
11890
|
+
"id": 10
|
|
11903
11891
|
},
|
|
11904
11892
|
"random_keypad": {
|
|
11905
11893
|
"type": "bool",
|
|
11906
|
-
"id":
|
|
11894
|
+
"id": 11
|
|
11907
11895
|
},
|
|
11908
11896
|
"passphrase_enable": {
|
|
11909
11897
|
"type": "bool",
|
|
@@ -11912,6 +11900,18 @@
|
|
|
11912
11900
|
"fido_enabled": {
|
|
11913
11901
|
"type": "bool",
|
|
11914
11902
|
"id": 101
|
|
11903
|
+
},
|
|
11904
|
+
"autolock_delay_ms": {
|
|
11905
|
+
"type": "uint32",
|
|
11906
|
+
"id": 102
|
|
11907
|
+
},
|
|
11908
|
+
"autoshutdown_delay_ms": {
|
|
11909
|
+
"type": "uint32",
|
|
11910
|
+
"id": 103
|
|
11911
|
+
},
|
|
11912
|
+
"label": {
|
|
11913
|
+
"type": "string",
|
|
11914
|
+
"id": 104
|
|
11915
11915
|
}
|
|
11916
11916
|
}
|
|
11917
11917
|
},
|
|
@@ -12427,68 +12427,14 @@
|
|
|
12427
12427
|
}
|
|
12428
12428
|
}
|
|
12429
12429
|
},
|
|
12430
|
-
"
|
|
12430
|
+
"DeviceSessionGet": {
|
|
12431
12431
|
"fields": {
|
|
12432
12432
|
"session_id": {
|
|
12433
|
-
"rule": "required",
|
|
12434
12433
|
"type": "bytes",
|
|
12435
12434
|
"id": 1
|
|
12436
12435
|
}
|
|
12437
12436
|
}
|
|
12438
12437
|
},
|
|
12439
|
-
"DeviceHostPassphrase": {
|
|
12440
|
-
"fields": {
|
|
12441
|
-
"passphrase": {
|
|
12442
|
-
"rule": "required",
|
|
12443
|
-
"type": "string",
|
|
12444
|
-
"id": 1
|
|
12445
|
-
}
|
|
12446
|
-
}
|
|
12447
|
-
},
|
|
12448
|
-
"DevicePassphraseOnDevice": {
|
|
12449
|
-
"fields": {}
|
|
12450
|
-
},
|
|
12451
|
-
"DeviceAttachPinOnDevice": {
|
|
12452
|
-
"fields": {}
|
|
12453
|
-
},
|
|
12454
|
-
"DeviceWalletSelect": {
|
|
12455
|
-
"oneofs": {
|
|
12456
|
-
"access": {
|
|
12457
|
-
"oneof": ["host_passphrase", "passphrase_on_device", "attach_pin_on_device"]
|
|
12458
|
-
}
|
|
12459
|
-
},
|
|
12460
|
-
"fields": {
|
|
12461
|
-
"host_passphrase": {
|
|
12462
|
-
"type": "DeviceHostPassphrase",
|
|
12463
|
-
"id": 1
|
|
12464
|
-
},
|
|
12465
|
-
"passphrase_on_device": {
|
|
12466
|
-
"type": "DevicePassphraseOnDevice",
|
|
12467
|
-
"id": 2
|
|
12468
|
-
},
|
|
12469
|
-
"attach_pin_on_device": {
|
|
12470
|
-
"type": "DeviceAttachPinOnDevice",
|
|
12471
|
-
"id": 3
|
|
12472
|
-
}
|
|
12473
|
-
}
|
|
12474
|
-
},
|
|
12475
|
-
"DeviceSessionOpen": {
|
|
12476
|
-
"oneofs": {
|
|
12477
|
-
"mode": {
|
|
12478
|
-
"oneof": ["resume", "select"]
|
|
12479
|
-
}
|
|
12480
|
-
},
|
|
12481
|
-
"fields": {
|
|
12482
|
-
"resume": {
|
|
12483
|
-
"type": "DeviceSessionResume",
|
|
12484
|
-
"id": 1
|
|
12485
|
-
},
|
|
12486
|
-
"select": {
|
|
12487
|
-
"type": "DeviceWalletSelect",
|
|
12488
|
-
"id": 2
|
|
12489
|
-
}
|
|
12490
|
-
}
|
|
12491
|
-
},
|
|
12492
12438
|
"DeviceSession": {
|
|
12493
12439
|
"fields": {
|
|
12494
12440
|
"session_id": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onekeyfe/hd-transport",
|
|
3
|
-
"version": "1.2.0-alpha.
|
|
3
|
+
"version": "1.2.0-alpha.20",
|
|
4
4
|
"description": "Transport layer abstractions and utilities for OneKey hardware SDK.",
|
|
5
5
|
"author": "OneKey",
|
|
6
6
|
"homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
|
|
@@ -28,5 +28,5 @@
|
|
|
28
28
|
"long": "^4.0.0",
|
|
29
29
|
"protobufjs": "^6.11.2"
|
|
30
30
|
},
|
|
31
|
-
"gitHead": "
|
|
31
|
+
"gitHead": "5fbc1ada90fd3cfda7e5ef08be368cb452018733"
|
|
32
32
|
}
|
package/src/constants.ts
CHANGED
|
@@ -1,50 +1,50 @@
|
|
|
1
1
|
// ---- Protocol V1 (Pro1 / Touch / Mini / Classic) ----
|
|
2
2
|
|
|
3
|
-
/** Protocol V1 USB report
|
|
3
|
+
/** Protocol V1 USB report marker, ASCII `?`. */
|
|
4
4
|
export const PROTOCOL_V1_REPORT_ID = 0x3f;
|
|
5
5
|
|
|
6
|
-
/** Protocol V1 envelope
|
|
6
|
+
/** Protocol V1 envelope marker, ASCII `#`. */
|
|
7
7
|
export const PROTOCOL_V1_HEADER_BYTE = 0x23;
|
|
8
8
|
|
|
9
|
-
/** Protocol V1
|
|
9
|
+
/** Protocol V1 payload bytes per chunk after the report marker. */
|
|
10
10
|
export const PROTOCOL_V1_CHUNK_PAYLOAD_SIZE = 63;
|
|
11
11
|
|
|
12
|
-
/** Protocol V1 USB packet
|
|
12
|
+
/** Protocol V1 USB packet length: report marker plus chunk payload. */
|
|
13
13
|
export const PROTOCOL_V1_USB_PACKET_SIZE = PROTOCOL_V1_CHUNK_PAYLOAD_SIZE + 1;
|
|
14
14
|
|
|
15
|
-
/** Protocol V1 message metadata
|
|
15
|
+
/** Protocol V1 message metadata: two-byte type plus four-byte payload length. */
|
|
16
16
|
export const PROTOCOL_V1_MESSAGE_HEADER_SIZE = 2 + 4;
|
|
17
17
|
|
|
18
|
-
/** Protocol V1 envelope metadata
|
|
18
|
+
/** Protocol V1 envelope metadata: `##`, message type, and payload length. */
|
|
19
19
|
export const PROTOCOL_V1_ENVELOPE_HEADER_SIZE = 1 + 1 + PROTOCOL_V1_MESSAGE_HEADER_SIZE;
|
|
20
20
|
|
|
21
21
|
// ---- Protocol V2 (Pro2 USB / BLE transports) ----
|
|
22
22
|
|
|
23
|
-
/**
|
|
24
|
-
export const PROTOCOL_V2_FRAME_MAX_BYTES =
|
|
23
|
+
/** Firmware Proto Link runtime limit for a complete V2 frame, including header and CRC. */
|
|
24
|
+
export const PROTOCOL_V2_FRAME_MAX_BYTES = 4200;
|
|
25
25
|
|
|
26
|
-
/**
|
|
26
|
+
/** FilesystemFileWrite chunk size over WebUSB. */
|
|
27
27
|
export const PROTOCOL_V2_WEBUSB_FILE_CHUNK_SIZE = 4000;
|
|
28
28
|
|
|
29
|
-
/**
|
|
29
|
+
/** FilesystemFileWrite chunk size over BLE. */
|
|
30
30
|
export const PROTOCOL_V2_BLE_FILE_CHUNK_SIZE = 1800;
|
|
31
31
|
|
|
32
|
-
/** BLE
|
|
32
|
+
/** BLE FilesystemFileRead chunk size, limited by the Pro2 1024-byte UART TX buffer. */
|
|
33
33
|
export const PROTOCOL_V2_BLE_FILE_READ_CHUNK_SIZE = 900;
|
|
34
34
|
|
|
35
|
-
/** Pro2 BLE/UART
|
|
35
|
+
/** Pro2 BLE/UART RX FIFO must hold a complete Proto Link frame. */
|
|
36
36
|
export const PROTOCOL_V2_BLE_FRAME_MAX_BYTES = 2048;
|
|
37
37
|
|
|
38
|
-
/** @deprecated
|
|
38
|
+
/** @deprecated Use the transport-specific WebUSB or BLE file chunk constant. */
|
|
39
39
|
export const PROTOCOL_V2_FILE_CHUNK_SIZE = PROTOCOL_V2_WEBUSB_FILE_CHUNK_SIZE;
|
|
40
40
|
|
|
41
41
|
/**
|
|
42
|
-
* Protocol V2
|
|
43
|
-
*
|
|
42
|
+
* Protocol V2 routing channel. USB reaches the main MCU directly, while BLE routes
|
|
43
|
+
* through the BLE coprocessor UART bridge.
|
|
44
44
|
*/
|
|
45
45
|
export const PROTOCOL_V2_CHANNEL_USB = 0;
|
|
46
46
|
export const PROTOCOL_V2_CHANNEL_BLE_UART = 1;
|
|
47
47
|
export const PROTOCOL_V2_CHANNEL_SOCKET = 2;
|
|
48
48
|
|
|
49
|
-
/** protobuf
|
|
49
|
+
/** packet_src for protobuf commands; firmware routes zero to the protobuf dispatcher. */
|
|
50
50
|
export const PROTOCOL_V2_PACKET_SRC_COMMAND = 0;
|
package/src/protocols/index.ts
CHANGED
|
@@ -6,7 +6,12 @@ import { decodeMessage as decodeV1Message } from './v1/receive';
|
|
|
6
6
|
import { createMessageFromName, createMessageFromType } from '../serialization/protobuf/messages';
|
|
7
7
|
import { encode as encodeProtobuf } from '../serialization/protobuf/encode';
|
|
8
8
|
import { decode as decodeProtobuf } from '../serialization/protobuf/decode';
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
decodeFrame as decodeV2Frame,
|
|
11
|
+
encodeProtobufFrame,
|
|
12
|
+
getAckSequence,
|
|
13
|
+
isAckFrame,
|
|
14
|
+
} from './v2';
|
|
10
15
|
|
|
11
16
|
import type { Root } from 'protobufjs/light';
|
|
12
17
|
|
|
@@ -71,6 +76,7 @@ export const ProtocolV1 = {
|
|
|
71
76
|
|
|
72
77
|
export const ProtocolV2 = {
|
|
73
78
|
isAckFrame,
|
|
79
|
+
getAckSequence,
|
|
74
80
|
|
|
75
81
|
inspectFrame(schemas: ProtocolV2Schemas, frame: Uint8Array) {
|
|
76
82
|
const { messageTypeId, pbPayload, seq } = decodeV2Frame(frame);
|
package/src/protocols/v2/crc8.ts
CHANGED
|
@@ -22,7 +22,7 @@ export const CRC8_TABLE = new Uint8Array([
|
|
|
22
22
|
]);
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
|
-
*
|
|
25
|
+
* Compute CRC-8 over the first len bytes using the firmware-compatible initial value.
|
|
26
26
|
*/
|
|
27
27
|
export function crc8(data: Uint8Array, len: number): number {
|
|
28
28
|
let crc = CRC8_INIT;
|
|
@@ -61,6 +61,13 @@ export function isAckFrame(data: Uint8Array): boolean {
|
|
|
61
61
|
return true;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
export function getAckSequence(data: Uint8Array): number | undefined {
|
|
65
|
+
if (!isAckFrame(data)) {
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
return data[6];
|
|
69
|
+
}
|
|
70
|
+
|
|
64
71
|
/**
|
|
65
72
|
* Parse and validate a Protocol V2 response frame.
|
|
66
73
|
*
|
|
@@ -43,7 +43,7 @@ export function encodeFrame(
|
|
|
43
43
|
const payloadLen = payload ? payload.length : 0;
|
|
44
44
|
const frameLen = payloadLen + PROTO_HEAD_CRC_SIZE;
|
|
45
45
|
if (frameLen > PROTOCOL_V2_FRAME_MAX_BYTES) {
|
|
46
|
-
throw new Error(`Protocol V2 frame too large: ${frameLen}`);
|
|
46
|
+
throw new Error(`Protocol V2 frame too large: ${frameLen} > ${PROTOCOL_V2_FRAME_MAX_BYTES}`);
|
|
47
47
|
}
|
|
48
48
|
const frame = new Uint8Array(frameLen);
|
|
49
49
|
|
|
@@ -17,6 +17,7 @@ export interface ProtocolV2LinkAdapter {
|
|
|
17
17
|
logger?: ProtocolV2SessionOptions['logger'];
|
|
18
18
|
logPrefix?: string;
|
|
19
19
|
createTimeoutError?: ProtocolV2SessionOptions['createTimeoutError'];
|
|
20
|
+
writeTimeoutMs?: number;
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
export type ProtocolV2LinkManagerOptions<Key> = {
|
|
@@ -128,6 +129,7 @@ export class ProtocolV2LinkManager<Key> {
|
|
|
128
129
|
logger: adapter.logger,
|
|
129
130
|
logPrefix: adapter.logPrefix,
|
|
130
131
|
createTimeoutError: adapter.createTimeoutError,
|
|
132
|
+
writeTimeoutMs: adapter.writeTimeoutMs,
|
|
131
133
|
});
|
|
132
134
|
const link = { adapter, session, state };
|
|
133
135
|
this.links.set(key, link);
|
|
@@ -38,6 +38,8 @@ export type ProtocolV2SessionOptions = {
|
|
|
38
38
|
createTimeoutError?: (name: string, timeoutMs: number) => Error;
|
|
39
39
|
sequenceCursor?: ProtocolV2SequenceCursor;
|
|
40
40
|
generation?: number;
|
|
41
|
+
writeTimeoutMs?: number;
|
|
42
|
+
deliveryTimeoutMs?: number;
|
|
41
43
|
};
|
|
42
44
|
|
|
43
45
|
export type ProtocolV2CallOptions = {
|
|
@@ -136,10 +138,11 @@ export async function withProtocolTimeout<T>(
|
|
|
136
138
|
}
|
|
137
139
|
}
|
|
138
140
|
|
|
139
|
-
//
|
|
140
|
-
//
|
|
141
|
-
//
|
|
142
|
-
export const PROTOCOL_V2_WRITE_WATCHDOG_TIMEOUT_MS =
|
|
141
|
+
// A transport write must never keep the serialized device queue pending forever.
|
|
142
|
+
// Callers must classify a timeout as link-fatal and reset the physical adapter so
|
|
143
|
+
// the losing Promise cannot continue on the next connection generation.
|
|
144
|
+
export const PROTOCOL_V2_WRITE_WATCHDOG_TIMEOUT_MS = 30_000;
|
|
145
|
+
export const PROTOCOL_V2_DELIVERY_WATCHDOG_TIMEOUT_MS = 5_000;
|
|
143
146
|
|
|
144
147
|
export class ProtocolV2Session {
|
|
145
148
|
private readonly options: ProtocolV2SessionOptions;
|
|
@@ -185,6 +188,8 @@ export class ProtocolV2Session {
|
|
|
185
188
|
logPrefix = 'ProtocolV2',
|
|
186
189
|
createTimeoutError,
|
|
187
190
|
generation = 0,
|
|
191
|
+
writeTimeoutMs = PROTOCOL_V2_WRITE_WATCHDOG_TIMEOUT_MS,
|
|
192
|
+
deliveryTimeoutMs = PROTOCOL_V2_DELIVERY_WATCHDOG_TIMEOUT_MS,
|
|
188
193
|
} = this.options;
|
|
189
194
|
|
|
190
195
|
const shouldReduceDebug = shouldReduceProtocolV2Debug(name);
|
|
@@ -201,7 +206,7 @@ export class ProtocolV2Session {
|
|
|
201
206
|
router,
|
|
202
207
|
seq: protoSeq,
|
|
203
208
|
});
|
|
204
|
-
//
|
|
209
|
+
// Suppress Protocol V2 TX frame logs to avoid excessive transport diagnostics.
|
|
205
210
|
/*
|
|
206
211
|
const txMetadata = ProtocolV2.inspectFrame(schemas, frame);
|
|
207
212
|
|
|
@@ -222,15 +227,10 @@ export class ProtocolV2Session {
|
|
|
222
227
|
);
|
|
223
228
|
}
|
|
224
229
|
|
|
225
|
-
// Lenient watchdog on the write phase only — see
|
|
226
|
-
// PROTOCOL_V2_WRITE_WATCHDOG_TIMEOUT_MS for the rationale.
|
|
227
230
|
await withProtocolTimeout(
|
|
228
231
|
writeFrame(frame, callContext),
|
|
229
|
-
|
|
230
|
-
() =>
|
|
231
|
-
new Error(
|
|
232
|
-
`Protocol V2 write timeout after ${PROTOCOL_V2_WRITE_WATCHDOG_TIMEOUT_MS}ms for ${name}`
|
|
233
|
-
)
|
|
232
|
+
writeTimeoutMs,
|
|
233
|
+
() => new Error(`Protocol V2 write timeout after ${writeTimeoutMs}ms for ${name}`)
|
|
234
234
|
);
|
|
235
235
|
|
|
236
236
|
// Cancellation flag for the read loop: when the response timeout fires,
|
|
@@ -238,6 +238,15 @@ export class ProtocolV2Session {
|
|
|
238
238
|
// consuming frames meant for the next call. The timeout callback flips the
|
|
239
239
|
// flag so the loop exits and discards any late frame.
|
|
240
240
|
const cancellation = { cancelled: false };
|
|
241
|
+
let resolveDelivery: () => void = () => undefined;
|
|
242
|
+
let deliveryConfirmed = false;
|
|
243
|
+
const deliveryPromise = new Promise<void>(resolve => {
|
|
244
|
+
resolveDelivery = () => {
|
|
245
|
+
if (deliveryConfirmed) return;
|
|
246
|
+
deliveryConfirmed = true;
|
|
247
|
+
resolve();
|
|
248
|
+
};
|
|
249
|
+
});
|
|
241
250
|
|
|
242
251
|
const readResponse = async (): Promise<MessageFromOneKey> => {
|
|
243
252
|
// Some Protocol V2 operations emit progress notifications before the
|
|
@@ -249,9 +258,16 @@ export class ProtocolV2Session {
|
|
|
249
258
|
// Timed out while waiting: drop the late frame and stop reading.
|
|
250
259
|
break;
|
|
251
260
|
}
|
|
252
|
-
const
|
|
253
|
-
if (
|
|
254
|
-
|
|
261
|
+
const ackSequence = ProtocolV2.getAckSequence(rxFrame);
|
|
262
|
+
if (ackSequence !== undefined) {
|
|
263
|
+
if (ackSequence === protoSeq) {
|
|
264
|
+
resolveDelivery();
|
|
265
|
+
}
|
|
266
|
+
} else {
|
|
267
|
+
// Some firmware versions return the protobuf response without a separate
|
|
268
|
+
// ACK. Receiving any valid response frame proves that the request arrived.
|
|
269
|
+
resolveDelivery();
|
|
270
|
+
// Suppress Protocol V2 RX frame logs to avoid excessive transport diagnostics.
|
|
255
271
|
/*
|
|
256
272
|
const rxMetadata = ProtocolV2.inspectFrame(schemas, rxFrame);
|
|
257
273
|
|
|
@@ -287,7 +303,7 @@ export class ProtocolV2Session {
|
|
|
287
303
|
throw new Error(`Protocol V2 read loop cancelled after timeout for ${name}`);
|
|
288
304
|
};
|
|
289
305
|
|
|
290
|
-
|
|
306
|
+
const responsePromise = withProtocolTimeout(
|
|
291
307
|
readResponse(),
|
|
292
308
|
callOptions.timeoutMs,
|
|
293
309
|
() =>
|
|
@@ -298,6 +314,31 @@ export class ProtocolV2Session {
|
|
|
298
314
|
cancellation.cancelled = true;
|
|
299
315
|
}
|
|
300
316
|
);
|
|
317
|
+
const deliverySignal = Promise.race([deliveryPromise, responsePromise.then(() => undefined)]);
|
|
318
|
+
const deliveryWatchdog = withProtocolTimeout(
|
|
319
|
+
deliverySignal,
|
|
320
|
+
deliveryTimeoutMs,
|
|
321
|
+
() => new Error(`Protocol V2 delivery timeout after ${deliveryTimeoutMs}ms for ${name}`),
|
|
322
|
+
() => {
|
|
323
|
+
cancellation.cancelled = true;
|
|
324
|
+
}
|
|
325
|
+
);
|
|
326
|
+
|
|
327
|
+
try {
|
|
328
|
+
const firstResult = await Promise.race([
|
|
329
|
+
deliveryWatchdog.then(() => ({ kind: 'delivered' as const })),
|
|
330
|
+
responsePromise.then(response => ({ kind: 'response' as const, response })),
|
|
331
|
+
]);
|
|
332
|
+
if (firstResult.kind === 'response') {
|
|
333
|
+
return firstResult.response;
|
|
334
|
+
}
|
|
335
|
+
return await responsePromise;
|
|
336
|
+
} catch (error) {
|
|
337
|
+
cancellation.cancelled = true;
|
|
338
|
+
deliveryWatchdog.catch(() => undefined);
|
|
339
|
+
responsePromise.catch(() => undefined);
|
|
340
|
+
throw error;
|
|
341
|
+
}
|
|
301
342
|
}
|
|
302
343
|
}
|
|
303
344
|
|
|
@@ -61,7 +61,7 @@ export abstract class ProtocolV2UsbTransportBase<Key> {
|
|
|
61
61
|
protected abstract createProtocolV2UsbTimeoutError(name: string, timeoutMs: number): Error;
|
|
62
62
|
|
|
63
63
|
protected onProtocolV2UsbLinkInvalidated(_key: Key, _reason: string): Promise<void> | void {
|
|
64
|
-
//
|
|
64
|
+
// Subclasses may clear protocol caches or emit platform-specific diagnostics.
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
protected async rotateProtocolV2UsbGeneration(key: Key, reason: string): Promise<number> {
|
package/src/types/messages.ts
CHANGED
|
@@ -4779,13 +4779,10 @@ export type DeviceReboot = {
|
|
|
4779
4779
|
|
|
4780
4780
|
// DeviceSettings
|
|
4781
4781
|
export type DeviceSettings = {
|
|
4782
|
-
label?: string;
|
|
4783
4782
|
bt_enable?: boolean;
|
|
4784
4783
|
language?: string;
|
|
4785
4784
|
wallpaper_path?: string;
|
|
4786
4785
|
brightness?: number;
|
|
4787
|
-
autolock_delay_ms?: number;
|
|
4788
|
-
autoshutdown_delay_ms?: number;
|
|
4789
4786
|
animation_enable?: boolean;
|
|
4790
4787
|
tap_to_wake?: boolean;
|
|
4791
4788
|
haptic_feedback?: boolean;
|
|
@@ -4795,6 +4792,9 @@ export type DeviceSettings = {
|
|
|
4795
4792
|
random_keypad?: boolean;
|
|
4796
4793
|
passphrase_enable?: boolean;
|
|
4797
4794
|
fido_enabled?: boolean;
|
|
4795
|
+
autolock_delay_ms?: number;
|
|
4796
|
+
autoshutdown_delay_ms?: number;
|
|
4797
|
+
label?: string;
|
|
4798
4798
|
};
|
|
4799
4799
|
|
|
4800
4800
|
// DeviceSettingsGet
|
|
@@ -5049,33 +5049,9 @@ export type ProtocolV2DeviceInfo = {
|
|
|
5049
5049
|
status?: DeviceStatus;
|
|
5050
5050
|
};
|
|
5051
5051
|
|
|
5052
|
-
//
|
|
5053
|
-
export type
|
|
5054
|
-
session_id
|
|
5055
|
-
};
|
|
5056
|
-
|
|
5057
|
-
// DeviceHostPassphrase
|
|
5058
|
-
export type DeviceHostPassphrase = {
|
|
5059
|
-
passphrase: string;
|
|
5060
|
-
};
|
|
5061
|
-
|
|
5062
|
-
// DevicePassphraseOnDevice
|
|
5063
|
-
export type DevicePassphraseOnDevice = {};
|
|
5064
|
-
|
|
5065
|
-
// DeviceAttachPinOnDevice
|
|
5066
|
-
export type DeviceAttachPinOnDevice = {};
|
|
5067
|
-
|
|
5068
|
-
// DeviceWalletSelect
|
|
5069
|
-
export type DeviceWalletSelect = {
|
|
5070
|
-
host_passphrase?: DeviceHostPassphrase;
|
|
5071
|
-
passphrase_on_device?: DevicePassphraseOnDevice;
|
|
5072
|
-
attach_pin_on_device?: DeviceAttachPinOnDevice;
|
|
5073
|
-
};
|
|
5074
|
-
|
|
5075
|
-
// DeviceSessionOpen
|
|
5076
|
-
export type DeviceSessionOpen = {
|
|
5077
|
-
resume?: DeviceSessionResume;
|
|
5078
|
-
select?: DeviceWalletSelect;
|
|
5052
|
+
// DeviceSessionGet
|
|
5053
|
+
export type DeviceSessionGet = {
|
|
5054
|
+
session_id?: string;
|
|
5079
5055
|
};
|
|
5080
5056
|
|
|
5081
5057
|
// DeviceSession
|
|
@@ -5905,12 +5881,7 @@ export type MessageType = {
|
|
|
5905
5881
|
DeviceInfoTargets: DeviceInfoTargets;
|
|
5906
5882
|
DeviceInfoTypes: DeviceInfoTypes;
|
|
5907
5883
|
DeviceInfoGet: DeviceInfoGet;
|
|
5908
|
-
|
|
5909
|
-
DeviceHostPassphrase: DeviceHostPassphrase;
|
|
5910
|
-
DevicePassphraseOnDevice: DevicePassphraseOnDevice;
|
|
5911
|
-
DeviceAttachPinOnDevice: DeviceAttachPinOnDevice;
|
|
5912
|
-
DeviceWalletSelect: DeviceWalletSelect;
|
|
5913
|
-
DeviceSessionOpen: DeviceSessionOpen;
|
|
5884
|
+
DeviceSessionGet: DeviceSessionGet;
|
|
5914
5885
|
DeviceSession: DeviceSession;
|
|
5915
5886
|
DeviceSessionAskPin: DeviceSessionAskPin;
|
|
5916
5887
|
DeviceStatus: DeviceStatus;
|
package/src/types/transport.ts
CHANGED
|
@@ -92,7 +92,7 @@ export type Transport = {
|
|
|
92
92
|
|
|
93
93
|
// resolves when the transport can be used; rejects when it cannot
|
|
94
94
|
init: ITransportInitFn;
|
|
95
|
-
stop(): void
|
|
95
|
+
stop(): void | Promise<void>;
|
|
96
96
|
|
|
97
97
|
configured: boolean;
|
|
98
98
|
version: string;
|
|
@@ -105,11 +105,7 @@ export type Transport = {
|
|
|
105
105
|
export type LowLevelDevice = OneKeyDeviceInfoBase & { id: string; name: string };
|
|
106
106
|
export type LowlevelTransportSharedPlugin = {
|
|
107
107
|
enumerate: () => Promise<LowLevelDevice[]>;
|
|
108
|
-
send: (
|
|
109
|
-
uuid: string,
|
|
110
|
-
data: string,
|
|
111
|
-
options?: { withoutResponse?: boolean }
|
|
112
|
-
) => Promise<void>;
|
|
108
|
+
send: (uuid: string, data: string, options?: { withoutResponse?: boolean }) => Promise<void>;
|
|
113
109
|
receive: (uuid?: string) => Promise<string>;
|
|
114
110
|
connect: (uuid: string) => Promise<void>;
|
|
115
111
|
disconnect: (uuid: string) => Promise<void>;
|