@onekeyfe/hd-core 1.2.0-alpha.145 → 1.2.0-alpha.147
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__/device-lifecycle-events.test.ts +1 -23
- package/__tests__/device-utils.test.ts +0 -8
- package/__tests__/deviceUploadNft.test.ts +0 -3
- package/__tests__/protocol-v2-resources.test.ts +89 -35
- package/__tests__/protocol-v2-unlock-policy.test.ts +0 -35
- package/__tests__/protocol-v2.test.ts +188 -49
- package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceUploadNft.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts.map +1 -1
- package/dist/core/index.d.ts +0 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/index.d.ts +20 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +298 -133
- package/dist/protocols/protocol-v2/resources.d.ts +7 -11
- package/dist/protocols/protocol-v2/resources.d.ts.map +1 -1
- package/dist/types/settings.d.ts +13 -0
- package/dist/types/settings.d.ts.map +1 -1
- package/dist/utils/deviceInfoUtils.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/api/FirmwareUpdateV4.ts +238 -61
- package/src/api/PromptWebDeviceAccess.ts +2 -2
- package/src/api/protocol-v2/DeviceUploadNft.ts +1 -5
- package/src/api/protocol-v2/DeviceUploadWallpaper.ts +1 -5
- package/src/core/index.ts +99 -11
- package/src/index.ts +4 -0
- package/src/protocols/protocol-v2/resources.ts +102 -92
- package/src/types/settings.ts +15 -0
- package/src/utils/deviceInfoUtils.ts +2 -7
package/src/core/index.ts
CHANGED
|
@@ -415,6 +415,10 @@ const onCallDevice = async (
|
|
|
415
415
|
if (method.payload?.onlyConnectBleDevice) {
|
|
416
416
|
preWarmCallbackTask?.resolve();
|
|
417
417
|
Log.debug('Call API - only connect ble device: ', device?.mainId);
|
|
418
|
+
// This early return bypasses the normal-path releaseTask at the end of the
|
|
419
|
+
// call; without it the task leaks and haunts every later queue snapshot
|
|
420
|
+
// and cancel sweep (field log: a completed task lingered for 6 minutes).
|
|
421
|
+
requestQueue.releaseTask(method.responseID);
|
|
418
422
|
return createResponseMessage(method.responseID, true, null);
|
|
419
423
|
}
|
|
420
424
|
|
|
@@ -914,13 +918,10 @@ function canSkipInitialize(method: BaseMethod, device: Device): boolean {
|
|
|
914
918
|
return true;
|
|
915
919
|
}
|
|
916
920
|
|
|
917
|
-
|
|
918
|
-
const
|
|
919
|
-
const message =
|
|
920
|
-
typeof typedError?.message === 'string' ? typedError.message : String(error ?? '');
|
|
921
|
+
function isRetryableBleProtocolV2ProbeError(method: BaseMethod, error: unknown) {
|
|
922
|
+
const message = error instanceof Error ? error.message : String(error ?? '');
|
|
921
923
|
return (
|
|
922
924
|
method.payload.connectProtocol === 'V2' &&
|
|
923
|
-
typedError?.errorCode === HardwareErrorCode.RuntimeError &&
|
|
924
925
|
message.includes('Device protocol mismatch') &&
|
|
925
926
|
message.includes('expected V2') &&
|
|
926
927
|
message.includes('did not respond to expected protocol')
|
|
@@ -941,7 +942,60 @@ export function isMissingDetectedProtocolV2Error(method: BaseMethod, error: unkn
|
|
|
941
942
|
* If the Bluetooth connection times out, retry up to 6 times
|
|
942
943
|
* @param retryCount - Current retry count (default 0)
|
|
943
944
|
*/
|
|
944
|
-
|
|
945
|
+
// device.acquire awaits a transport reply with no deadline of its own; a
|
|
946
|
+
// transport that never settles (field case: Electron main lost an IPC reply,
|
|
947
|
+
// "reply was never sent" after 5 minutes) hangs the call forever and cancel()
|
|
948
|
+
// only takes effect at poll checkpoints. Race acquire against a deadline and
|
|
949
|
+
// the caller's abort signal so the hang is bounded and cancel is immediate.
|
|
950
|
+
const BLE_ACQUIRE_DEADLINE_MS = 60 * 1000;
|
|
951
|
+
|
|
952
|
+
function raceBleAcquire<T>(acquirePromise: Promise<T>, abortSignal?: AbortSignal): Promise<T> {
|
|
953
|
+
return new Promise<T>((resolve, reject) => {
|
|
954
|
+
let settled = false;
|
|
955
|
+
const settle = (fn: () => void) => {
|
|
956
|
+
if (settled) return;
|
|
957
|
+
settled = true;
|
|
958
|
+
clearTimeout(deadline);
|
|
959
|
+
abortSignal?.removeEventListener('abort', onAbort);
|
|
960
|
+
fn();
|
|
961
|
+
};
|
|
962
|
+
const onAbort = () =>
|
|
963
|
+
settle(() => reject(ERRORS.TypedError(HardwareErrorCode.CallQueueActionCancelled)));
|
|
964
|
+
const deadline = setTimeout(
|
|
965
|
+
() =>
|
|
966
|
+
settle(() =>
|
|
967
|
+
reject(
|
|
968
|
+
ERRORS.TypedError(
|
|
969
|
+
HardwareErrorCode.BleTimeoutError,
|
|
970
|
+
`BLE acquire exceeded ${BLE_ACQUIRE_DEADLINE_MS}ms deadline`
|
|
971
|
+
)
|
|
972
|
+
)
|
|
973
|
+
),
|
|
974
|
+
BLE_ACQUIRE_DEADLINE_MS
|
|
975
|
+
);
|
|
976
|
+
// Attach before any early return so a late settlement of acquirePromise
|
|
977
|
+
// is always consumed — an abort or deadline must never leave the acquire
|
|
978
|
+
// rejection unhandled.
|
|
979
|
+
acquirePromise.then(
|
|
980
|
+
value => settle(() => resolve(value)),
|
|
981
|
+
error => settle(() => reject(error))
|
|
982
|
+
);
|
|
983
|
+
if (abortSignal) {
|
|
984
|
+
if (abortSignal.aborted) {
|
|
985
|
+
onAbort();
|
|
986
|
+
return;
|
|
987
|
+
}
|
|
988
|
+
abortSignal.addEventListener('abort', onAbort);
|
|
989
|
+
}
|
|
990
|
+
});
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
async function connectDeviceForBle(
|
|
994
|
+
method: BaseMethod,
|
|
995
|
+
device: Device,
|
|
996
|
+
abortSignal?: AbortSignal,
|
|
997
|
+
retryCount = 0
|
|
998
|
+
) {
|
|
945
999
|
try {
|
|
946
1000
|
if (method.payload.forceProtocolDetection && device.hasDeviceAcquire()) {
|
|
947
1001
|
await device.release();
|
|
@@ -952,9 +1006,43 @@ async function connectDeviceForBle(method: BaseMethod, device: Device, retryCoun
|
|
|
952
1006
|
!device.commands ||
|
|
953
1007
|
device.commands.disposed;
|
|
954
1008
|
if (shouldAcquire) {
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
1009
|
+
// The deadline/abort guards are scoped to the desktop electron
|
|
1010
|
+
// transport: its IPC acquire is the only path with a proven
|
|
1011
|
+
// never-settling failure mode, while react-native/lowlevel acquire may
|
|
1012
|
+
// legitimately block on a user-driven system bonding prompt for longer
|
|
1013
|
+
// than any sane deadline. Other envs keep the plain acquire unchanged.
|
|
1014
|
+
const useAcquireGuards = DataManager.getSettings('env') === 'desktop-web-ble';
|
|
1015
|
+
// A cancel landing during the retry backoff must not start a new acquire.
|
|
1016
|
+
if (useAcquireGuards && abortSignal?.aborted) {
|
|
1017
|
+
throw ERRORS.TypedError(HardwareErrorCode.CallQueueActionCancelled);
|
|
1018
|
+
}
|
|
1019
|
+
if (!useAcquireGuards) {
|
|
1020
|
+
await device.acquire(method.payload.connectProtocol, {
|
|
1021
|
+
forceProtocolDetection: method.payload.forceProtocolDetection,
|
|
1022
|
+
});
|
|
1023
|
+
} else {
|
|
1024
|
+
try {
|
|
1025
|
+
await raceBleAcquire(
|
|
1026
|
+
device.acquire(method.payload.connectProtocol, {
|
|
1027
|
+
forceProtocolDetection: method.payload.forceProtocolDetection,
|
|
1028
|
+
}),
|
|
1029
|
+
abortSignal
|
|
1030
|
+
);
|
|
1031
|
+
} catch (err) {
|
|
1032
|
+
// A deadline hit means the transport is wedged mid-acquire; drop the
|
|
1033
|
+
// link before the retry so it cold-connects instead of stacking a
|
|
1034
|
+
// second connect onto the half-open one.
|
|
1035
|
+
if (
|
|
1036
|
+
err.errorCode === HardwareErrorCode.BleTimeoutError &&
|
|
1037
|
+
device.mainId &&
|
|
1038
|
+
device.deviceConnector
|
|
1039
|
+
) {
|
|
1040
|
+
await device.deviceConnector.disconnect(device.mainId).catch(() => undefined);
|
|
1041
|
+
device.markTransportDisconnected();
|
|
1042
|
+
}
|
|
1043
|
+
throw err;
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
958
1046
|
}
|
|
959
1047
|
if (method.payload?.onlyConnectBleDevice) {
|
|
960
1048
|
if (shouldAcquire) {
|
|
@@ -1000,7 +1088,7 @@ async function connectDeviceForBle(method: BaseMethod, device: Device, retryCoun
|
|
|
1000
1088
|
const nextRetry = retryCount + 1;
|
|
1001
1089
|
Log.debug(`Bluetooth connection will retry, retry count: ${nextRetry}`);
|
|
1002
1090
|
await wait(3000);
|
|
1003
|
-
await connectDeviceForBle(method, device, nextRetry);
|
|
1091
|
+
await connectDeviceForBle(method, device, abortSignal, nextRetry);
|
|
1004
1092
|
} else {
|
|
1005
1093
|
throw err;
|
|
1006
1094
|
}
|
|
@@ -1105,7 +1193,7 @@ const ensureConnected = async (
|
|
|
1105
1193
|
if (abort()) {
|
|
1106
1194
|
return;
|
|
1107
1195
|
}
|
|
1108
|
-
await connectDeviceForBle(method, device);
|
|
1196
|
+
await connectDeviceForBle(method, device, abortSignal);
|
|
1109
1197
|
}
|
|
1110
1198
|
resolve(device);
|
|
1111
1199
|
return;
|
package/src/index.ts
CHANGED
|
@@ -21,6 +21,10 @@ export { executeCallback, cleanupCallback };
|
|
|
21
21
|
export { preloadSessionCache } from './device/Device';
|
|
22
22
|
export { projectFeatures as projectDeviceStateFeatures } from './device/DeviceStateProjector';
|
|
23
23
|
export { getMethodSupportedProtocols } from './api/utils';
|
|
24
|
+
export {
|
|
25
|
+
parseProtocolV2ResourceManifest,
|
|
26
|
+
selectProtocolV2ResourceManifestFiles,
|
|
27
|
+
} from './protocols/protocol-v2/resources';
|
|
24
28
|
export { prepareFirmwareUpdateV4MemoryHost } from './api/firmware/FirmwareMemoryHost';
|
|
25
29
|
export type {
|
|
26
30
|
FirmwareMemoryArtifact,
|
|
@@ -1,20 +1,29 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import type {
|
|
2
|
+
IProtocolV2ResourceManifest,
|
|
3
|
+
IProtocolV2ResourceManifestFile,
|
|
4
|
+
IProtocolV2Resources,
|
|
5
|
+
} from '../../types';
|
|
6
|
+
import type { FirmwareUpdateV4Target } from '../../types/api/firmwareUpdate';
|
|
4
7
|
|
|
5
8
|
export const PROTOCOL_V2_BOOT_RESOURCE_PACKAGE_PATH =
|
|
6
9
|
'vol0:/loaders/bootloader/boot_resource.okpkg';
|
|
7
10
|
export const PROTOCOL_V2_BOOT_RESOURCE_PACKAGE_STAGING_PATH = `${PROTOCOL_V2_BOOT_RESOURCE_PACKAGE_PATH}.staging`;
|
|
8
11
|
export const PROTOCOL_V2_ROM_PARAMS_PACKAGE_PATH = 'vol0:/loaders/rom/params.okpkg';
|
|
9
|
-
export const PROTOCOL_V2_RESOURCE_PACKAGE_HEADER_SIZE = 0x5f90;
|
|
10
12
|
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const
|
|
13
|
+
const SHA256_HEX_LENGTH = 64;
|
|
14
|
+
|
|
15
|
+
function normalizeHex(value: unknown, expectedLength: number, field: string): string {
|
|
16
|
+
if (typeof value !== 'string') {
|
|
17
|
+
throw new Error(`Invalid Pro2 resource ${field}: expected a hexadecimal string`);
|
|
18
|
+
}
|
|
19
|
+
const normalized = value.replace(/^0x/i, '').toLowerCase();
|
|
20
|
+
if (normalized.length !== expectedLength || !/^[0-9a-f]+$/.test(normalized)) {
|
|
21
|
+
throw new Error(
|
|
22
|
+
`Invalid Pro2 resource ${field}: expected ${expectedLength} hexadecimal characters`
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
return normalized;
|
|
26
|
+
}
|
|
18
27
|
|
|
19
28
|
/** Validate a complete Pro2 stable resource set from remote configuration. */
|
|
20
29
|
export function parseProtocolV2Resources(value: unknown): IProtocolV2Resources | undefined {
|
|
@@ -49,113 +58,114 @@ export function parseProtocolV2Resources(value: unknown): IProtocolV2Resources |
|
|
|
49
58
|
};
|
|
50
59
|
}
|
|
51
60
|
|
|
52
|
-
const
|
|
61
|
+
const PROTOCOL_V2_RESOURCE_MANIFEST_DEVICE_ROOTS = [
|
|
62
|
+
'vol0:/bundles/',
|
|
63
|
+
'vol0:/loaders/rom/',
|
|
64
|
+
] as const;
|
|
53
65
|
|
|
54
|
-
function
|
|
66
|
+
function isAllowedManifestDevicePath(path: string): boolean {
|
|
55
67
|
if (
|
|
68
|
+
!path.endsWith('.okpkg') ||
|
|
56
69
|
path.includes('\\') ||
|
|
57
70
|
path.includes('//') ||
|
|
58
|
-
[...path].some(char => {
|
|
59
|
-
const code = char.charCodeAt(0);
|
|
60
|
-
return code <= 0x1f || code === 0x7f;
|
|
61
|
-
}) ||
|
|
62
71
|
path.split('/').some(part => part === '.' || part === '..')
|
|
63
72
|
) {
|
|
64
73
|
return false;
|
|
65
74
|
}
|
|
66
|
-
if (path ===
|
|
75
|
+
if (path === PROTOCOL_V2_BOOT_RESOURCE_PACKAGE_PATH) {
|
|
67
76
|
return true;
|
|
68
77
|
}
|
|
69
|
-
return (
|
|
70
|
-
path.endsWith('.okpkg') && PROTOCOL_V2_RESOURCE_DEVICE_ROOTS.some(root => path.startsWith(root))
|
|
71
|
-
);
|
|
78
|
+
return PROTOCOL_V2_RESOURCE_MANIFEST_DEVICE_ROOTS.some(root => path.startsWith(root));
|
|
72
79
|
}
|
|
73
80
|
|
|
74
|
-
function
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
81
|
+
function assertManifestString(value: unknown, field: string): string {
|
|
82
|
+
if (typeof value !== 'string' || value.length === 0) {
|
|
83
|
+
throw new Error(`Invalid Pro2 resource manifest ${field}`);
|
|
84
|
+
}
|
|
85
|
+
return value;
|
|
78
86
|
}
|
|
79
87
|
|
|
80
|
-
function
|
|
81
|
-
const
|
|
82
|
-
PROTOCOL_V2_RESOURCE_PACKAGE_FLEXIBLE_OFFSET,
|
|
83
|
-
PROTOCOL_V2_RESOURCE_PACKAGE_FLEXIBLE_OFFSET + PROTOCOL_V2_RESOURCE_PACKAGE_FLEXIBLE_SIZE
|
|
84
|
-
);
|
|
85
|
-
const terminator = metadata.indexOf(0);
|
|
86
|
-
const pathBytes = terminator === -1 ? metadata : metadata.slice(0, terminator);
|
|
87
|
-
const padding = terminator === -1 ? new Uint8Array(0) : metadata.slice(terminator);
|
|
88
|
+
function assertManifestRelativePath(value: unknown, field: string): string {
|
|
89
|
+
const path = assertManifestString(value, field);
|
|
88
90
|
if (
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
91
|
+
path.startsWith('/') ||
|
|
92
|
+
path.includes('\\') ||
|
|
93
|
+
path.includes(':') ||
|
|
94
|
+
path.split('/').some(part => !part || part === '.' || part === '..')
|
|
92
95
|
) {
|
|
93
|
-
throw new Error(
|
|
94
|
-
}
|
|
95
|
-
const path = readAscii(pathBytes, 0, pathBytes.byteLength);
|
|
96
|
-
if (!isAllowedResourceDevicePath(path)) {
|
|
97
|
-
throw new Error(`Invalid Pro2 RESOURCE package device path: ${path}`);
|
|
96
|
+
throw new Error(`Invalid Pro2 resource manifest ${field}`);
|
|
98
97
|
}
|
|
99
98
|
return path;
|
|
100
99
|
}
|
|
101
100
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
101
|
+
function parseProtocolV2ResourceManifestFile(
|
|
102
|
+
value: unknown,
|
|
103
|
+
index: number
|
|
104
|
+
): IProtocolV2ResourceManifestFile {
|
|
105
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
106
|
+
throw new Error(`Invalid Pro2 resource manifest files[${index}]`);
|
|
107
|
+
}
|
|
108
|
+
const file = value as Partial<IProtocolV2ResourceManifestFile>;
|
|
109
|
+
const archivePath = assertManifestRelativePath(file.archive_path, `files[${index}].archive_path`);
|
|
110
|
+
const originalName =
|
|
111
|
+
file.original_name === undefined
|
|
112
|
+
? archivePath.split('/').pop() ?? archivePath
|
|
113
|
+
: assertManifestRelativePath(file.original_name, `files[${index}].original_name`);
|
|
114
|
+
if (originalName.includes('/')) {
|
|
115
|
+
throw new Error(`Invalid Pro2 resource manifest files[${index}].original_name`);
|
|
116
|
+
}
|
|
117
|
+
const devicePath = assertManifestString(file.device_path, `files[${index}].device_path`);
|
|
118
|
+
if (!isAllowedManifestDevicePath(devicePath)) {
|
|
119
|
+
throw new Error(`Invalid Pro2 resource manifest files[${index}].device_path`);
|
|
120
|
+
}
|
|
121
|
+
if (!Number.isSafeInteger(file.size) || Number(file.size) <= 0) {
|
|
122
|
+
throw new Error(`Invalid Pro2 resource manifest files[${index}].size`);
|
|
123
|
+
}
|
|
124
|
+
const digest = normalizeHex(file.sha256, SHA256_HEX_LENGTH, `files[${index}].sha256`);
|
|
125
|
+
if (!archivePath.endsWith('.okpkg') || !originalName.endsWith('.okpkg')) {
|
|
126
|
+
throw new Error(`Invalid Pro2 resource manifest files[${index}] package extension`);
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
archive_path: archivePath,
|
|
130
|
+
original_name: originalName,
|
|
131
|
+
device_path: devicePath,
|
|
132
|
+
size: Number(file.size),
|
|
133
|
+
sha256: digest,
|
|
134
|
+
...(file.signed === undefined ? {} : { signed: file.signed }),
|
|
135
|
+
...(file.sig_algo === undefined ? {} : { sig_algo: file.sig_algo }),
|
|
136
|
+
...(file.payload_version === undefined ? {} : { payload_version: file.payload_version }),
|
|
137
|
+
};
|
|
138
|
+
}
|
|
109
139
|
|
|
110
|
-
export function
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
const
|
|
119
|
-
const
|
|
120
|
-
const
|
|
140
|
+
export function parseProtocolV2ResourceManifest(value: unknown): IProtocolV2ResourceManifest {
|
|
141
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
142
|
+
throw new Error('Invalid Pro2 resource manifest');
|
|
143
|
+
}
|
|
144
|
+
const manifest = value as Partial<IProtocolV2ResourceManifest>;
|
|
145
|
+
if (!Array.isArray(manifest.files)) {
|
|
146
|
+
throw new Error('Invalid Pro2 resource manifest files');
|
|
147
|
+
}
|
|
148
|
+
const files = manifest.files.map(parseProtocolV2ResourceManifestFile);
|
|
149
|
+
const devicePaths = new Set(files.map(file => file.device_path));
|
|
150
|
+
const archivePaths = new Set(files.map(file => file.archive_path));
|
|
121
151
|
if (
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
headerLength !== PROTOCOL_V2_RESOURCE_PACKAGE_HEADER_SIZE ||
|
|
126
|
-
payloadLength <= 0 ||
|
|
127
|
-
headerLength + payloadLength !== packageSize
|
|
152
|
+
files.length === 0 ||
|
|
153
|
+
devicePaths.size !== files.length ||
|
|
154
|
+
archivePaths.size !== files.length
|
|
128
155
|
) {
|
|
129
|
-
throw new Error('Invalid Pro2
|
|
156
|
+
throw new Error('Invalid Pro2 resource manifest file set');
|
|
130
157
|
}
|
|
131
|
-
|
|
132
|
-
const packedVersion = view.getUint32(0x10, true);
|
|
133
158
|
return {
|
|
134
|
-
|
|
135
|
-
Math.floor(packedVersion / 0x10000) % 0x100,
|
|
136
|
-
Math.floor(packedVersion / 0x100) % 0x100,
|
|
137
|
-
packedVersion % 0x100,
|
|
138
|
-
],
|
|
139
|
-
payloadLength,
|
|
140
|
-
devicePath: readResourceDevicePath(bytes),
|
|
141
|
-
payloadHash: bytesToHex(
|
|
142
|
-
bytes.slice(
|
|
143
|
-
PROTOCOL_V2_RESOURCE_PACKAGE_PAYLOAD_HASH_OFFSET,
|
|
144
|
-
PROTOCOL_V2_RESOURCE_PACKAGE_PAYLOAD_HASH_OFFSET + PROTOCOL_V2_RESOURCE_PACKAGE_HASH_SIZE
|
|
145
|
-
)
|
|
146
|
-
),
|
|
147
|
-
headerHash: bytesToHex(
|
|
148
|
-
bytes.slice(
|
|
149
|
-
PROTOCOL_V2_RESOURCE_PACKAGE_HEADER_HASH_OFFSET,
|
|
150
|
-
PROTOCOL_V2_RESOURCE_PACKAGE_HEADER_HASH_OFFSET + PROTOCOL_V2_RESOURCE_PACKAGE_HASH_SIZE
|
|
151
|
-
)
|
|
152
|
-
),
|
|
159
|
+
files,
|
|
153
160
|
};
|
|
154
161
|
}
|
|
155
162
|
|
|
156
|
-
export function
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
163
|
+
export function selectProtocolV2ResourceManifestFiles({
|
|
164
|
+
manifest,
|
|
165
|
+
targetsToUpdate,
|
|
166
|
+
}: {
|
|
167
|
+
manifest: IProtocolV2ResourceManifest;
|
|
168
|
+
targetsToUpdate: readonly FirmwareUpdateV4Target[];
|
|
169
|
+
}): IProtocolV2ResourceManifestFile[] {
|
|
170
|
+
return targetsToUpdate.includes('resource') ? [...manifest.files] : [];
|
|
161
171
|
}
|
package/src/types/settings.ts
CHANGED
|
@@ -74,6 +74,21 @@ export type IProtocolV2Resources = {
|
|
|
74
74
|
source: IProtocolV2ResourceSource;
|
|
75
75
|
};
|
|
76
76
|
|
|
77
|
+
export type IProtocolV2ResourceManifestFile = {
|
|
78
|
+
archive_path: string;
|
|
79
|
+
original_name?: string;
|
|
80
|
+
device_path: string;
|
|
81
|
+
size: number;
|
|
82
|
+
sha256: string;
|
|
83
|
+
signed?: boolean;
|
|
84
|
+
sig_algo?: string;
|
|
85
|
+
payload_version?: string | null;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
export type IProtocolV2ResourceManifest = {
|
|
89
|
+
files: IProtocolV2ResourceManifestFile[];
|
|
90
|
+
};
|
|
91
|
+
|
|
77
92
|
/** STM32 firmware config */
|
|
78
93
|
export type IFirmwareReleaseInfo = {
|
|
79
94
|
required: boolean;
|
|
@@ -30,13 +30,8 @@ export const getDeviceTypeByBleName = (name?: string): IDeviceType => {
|
|
|
30
30
|
if (/^T/i.test(name)) return EDeviceType.Touch;
|
|
31
31
|
if (/^Touch/i.test(name)) return EDeviceType.Touch;
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
if (/\
|
|
35
|
-
return EDeviceType.Pro2;
|
|
36
|
-
}
|
|
37
|
-
if (/\bNeo\b/i.test(name) || /^Neo/i.test(name) || /^(?:OneKey)?Neo/i.test(compactName)) {
|
|
38
|
-
return EDeviceType.Neo;
|
|
39
|
-
}
|
|
33
|
+
if (/\bPro\s*2\b/i.test(name) || /^Pro2/i.test(name)) return EDeviceType.Pro2;
|
|
34
|
+
if (/\bNeo\b/i.test(name) || /^Neo/i.test(name)) return EDeviceType.Neo;
|
|
40
35
|
if (/\bPro\b/i.test(name) || /^Pro/i.test(name)) return EDeviceType.Pro;
|
|
41
36
|
|
|
42
37
|
return EDeviceType.Unknown;
|