@onekeyfe/hd-core 1.2.0-alpha.157 → 1.2.0-alpha.159
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-utils.test.ts +2 -0
- package/__tests__/firmware-update/firmware-update-prepared-plan.test.ts +1 -4
- package/__tests__/protocol-v2-resources.test.ts +1 -3
- package/__tests__/protocol-v2.test.ts +80 -37
- package/dist/api/FirmwareUpdateV4.d.ts +3 -1
- package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareUpdatePlan.d.ts +0 -15
- package/dist/api/firmware/FirmwareUpdatePlan.d.ts.map +1 -1
- package/dist/api/firmware/FirmwareUpdatePreparedPlan.d.ts.map +1 -1
- package/dist/data-manager/TransportManager.d.ts.map +1 -1
- package/dist/index.d.ts +2 -22
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +69 -234
- package/dist/utils/deviceInfoUtils.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/api/FirmwareUpdateV4.ts +76 -185
- package/src/api/firmware/FirmwareUpdatePlan.ts +0 -41
- package/src/api/firmware/FirmwareUpdatePreparedPlan.ts +2 -0
- package/src/data-manager/TransportManager.ts +3 -1
- package/src/index.ts +0 -6
- package/src/types/api/firmwareUpdate.ts +1 -1
- package/src/utils/deviceInfoUtils.ts +3 -1
- package/__tests__/firmware-memory-host.test.ts +0 -126
- package/dist/api/firmware/FirmwareMemoryHost.d.ts +0 -22
- package/dist/api/firmware/FirmwareMemoryHost.d.ts.map +0 -1
- package/src/api/firmware/FirmwareMemoryHost.ts +0 -143
|
@@ -32,12 +32,13 @@ import {
|
|
|
32
32
|
} from '../protocols/protocol-v2';
|
|
33
33
|
import { requestProtocolV2DeviceInfo } from '../protocols/protocol-v2/features';
|
|
34
34
|
import {
|
|
35
|
+
PROTOCOL_V2_BOOT_RESOURCE_PACKAGE_PATH,
|
|
35
36
|
PROTOCOL_V2_BOOT_RESOURCE_PACKAGE_STAGING_PATH,
|
|
36
37
|
PROTOCOL_V2_RESOURCE_PACKAGE_HEADER_SIZE,
|
|
38
|
+
type ProtocolV2ResourcePackageHeader,
|
|
37
39
|
isProtocolV2ResourceArchiveEntryName,
|
|
38
40
|
parseProtocolV2ResourcePackage,
|
|
39
41
|
parseProtocolV2ResourcePackageHeader,
|
|
40
|
-
type ProtocolV2ResourcePackageHeader,
|
|
41
42
|
} from '../protocols/protocol-v2/resources';
|
|
42
43
|
import {
|
|
43
44
|
getProtocolV2UnknownErrorText,
|
|
@@ -48,20 +49,12 @@ import {
|
|
|
48
49
|
readFirmwareByteSourceFully,
|
|
49
50
|
writeFirmwareByteSource,
|
|
50
51
|
} from './firmware/FirmwareArtifactSource';
|
|
51
|
-
import {
|
|
52
|
-
registerFirmwareUpdateHostBinding,
|
|
53
|
-
resolveFirmwareUpdateHostBinding,
|
|
54
|
-
unregisterFirmwareUpdateHostBinding,
|
|
55
|
-
} from './firmware/FirmwareHostBinding';
|
|
52
|
+
import { resolveFirmwareUpdateHostBinding } from './firmware/FirmwareHostBinding';
|
|
56
53
|
import {
|
|
57
54
|
assertFirmwareUpdatePreparedPlanBinding,
|
|
58
55
|
assertFirmwareUpdatePreparedPlanDeviceIdentity,
|
|
59
|
-
prepareFirmwareUpdatePlan,
|
|
60
56
|
validateFirmwareUpdatePreparedPlan,
|
|
61
57
|
} from './firmware/FirmwareUpdatePreparedPlan';
|
|
62
|
-
import { prepareFirmwareUpdateV4MemoryHost } from './firmware/FirmwareMemoryHost';
|
|
63
|
-
import { buildProtocolV2LocalFirmwareUpdatePlan } from './firmware/FirmwareUpdatePlan';
|
|
64
|
-
|
|
65
58
|
import type {
|
|
66
59
|
FirmwareArtifactReference,
|
|
67
60
|
FirmwareUpdateV4Params,
|
|
@@ -78,11 +71,6 @@ import type {
|
|
|
78
71
|
KnownDevice,
|
|
79
72
|
} from '../types';
|
|
80
73
|
import type { FirmwareByteSource } from './firmware/FirmwareArtifactSource';
|
|
81
|
-
import type {
|
|
82
|
-
FirmwareMemoryArtifact,
|
|
83
|
-
FirmwareMemoryArtifactEntry,
|
|
84
|
-
FirmwareUpdateV4MemoryHost,
|
|
85
|
-
} from './firmware/FirmwareMemoryHost';
|
|
86
74
|
|
|
87
75
|
const Log = getLogger(LoggerNames.Method);
|
|
88
76
|
|
|
@@ -231,7 +219,6 @@ type ProtocolV2ResourceBundleSource = {
|
|
|
231
219
|
|
|
232
220
|
type ProtocolV2LocalResourceArchive = {
|
|
233
221
|
binary: ArrayBuffer;
|
|
234
|
-
materializedEntries: FirmwareMemoryArtifactEntry[];
|
|
235
222
|
resources: Array<{
|
|
236
223
|
entryName: string;
|
|
237
224
|
binary: ArrayBuffer;
|
|
@@ -302,13 +289,9 @@ const PROTOCOL_V2_FIRMWARE_STAGING_PATHS = new Set(
|
|
|
302
289
|
)
|
|
303
290
|
);
|
|
304
291
|
|
|
305
|
-
const isProtocolV2BootResourcePackagePath = (devicePath: string) =>
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
return (
|
|
309
|
-
normalized.startsWith('vol0:/loaders/bootloader/') && normalized.endsWith('.okpkg.staging')
|
|
310
|
-
);
|
|
311
|
-
};
|
|
292
|
+
const isProtocolV2BootResourcePackagePath = (devicePath: string) =>
|
|
293
|
+
typeof devicePath === 'string' &&
|
|
294
|
+
devicePath.toLowerCase() === PROTOCOL_V2_BOOT_RESOURCE_PACKAGE_STAGING_PATH;
|
|
312
295
|
|
|
313
296
|
const PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID = new Map<
|
|
314
297
|
number,
|
|
@@ -797,15 +780,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
797
780
|
this.params.resourceArchiveBinary &&
|
|
798
781
|
this.params.targetsToUpdate?.includes('resource')
|
|
799
782
|
) {
|
|
800
|
-
|
|
801
|
-
features: deviceFeatures,
|
|
802
|
-
firmwareType,
|
|
803
|
-
});
|
|
804
|
-
try {
|
|
805
|
-
return await this.runProtocolV2PreparedArtifacts(deviceFeatures, firmwareType);
|
|
806
|
-
} finally {
|
|
807
|
-
localMemoryHost.release();
|
|
808
|
-
}
|
|
783
|
+
return this.runProtocolV2DirectArtifacts({});
|
|
809
784
|
}
|
|
810
785
|
|
|
811
786
|
const hasPreparedComponentArtifacts = Object.values(this.params.componentArtifacts ?? {}).some(
|
|
@@ -818,12 +793,12 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
818
793
|
let fwBinaryMap: ProtocolV2TargetBinary[] = [];
|
|
819
794
|
let bootloaderBinary: ArrayBuffer | null = null;
|
|
820
795
|
let installItems: ProtocolV2InstallItem[] | undefined;
|
|
821
|
-
let
|
|
796
|
+
let explicitInstallItems: ProtocolV2InstallItem[] | undefined;
|
|
822
797
|
try {
|
|
823
798
|
this.postTipMessage(FirmwareUpdateTipMessage.StartDownloadFirmware);
|
|
824
799
|
fwBinaryMap = this.collectExplicitTargetBinaries();
|
|
825
800
|
bootloaderBinary = this.prepareBootloaderBinary();
|
|
826
|
-
|
|
801
|
+
explicitInstallItems = this.buildProtocolV2InstallItems({
|
|
827
802
|
bootloaderBinary,
|
|
828
803
|
fwBinaryMap,
|
|
829
804
|
});
|
|
@@ -879,15 +854,9 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
879
854
|
deviceFeatures,
|
|
880
855
|
firmwareType
|
|
881
856
|
);
|
|
882
|
-
resourceMemoryHost = await this.prepareProtocolV2LocalMemoryHost({
|
|
883
|
-
features: deviceFeatures,
|
|
884
|
-
firmwareType,
|
|
885
|
-
availableInstallItems: installItems ?? explicitInstallItems,
|
|
886
|
-
});
|
|
887
857
|
}
|
|
888
858
|
this.postTipMessage(FirmwareUpdateTipMessage.FinishDownloadFirmware);
|
|
889
859
|
} catch (err) {
|
|
890
|
-
resourceMemoryHost?.release();
|
|
891
860
|
if (
|
|
892
861
|
typeof err === 'object' &&
|
|
893
862
|
err !== null &&
|
|
@@ -902,12 +871,11 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
902
871
|
throw normalizeFirmwarePreparationError(err);
|
|
903
872
|
}
|
|
904
873
|
|
|
905
|
-
if (
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
}
|
|
874
|
+
if (wantsResources && this.params.resourceArchiveBinary) {
|
|
875
|
+
return this.runProtocolV2DirectArtifacts({
|
|
876
|
+
availableInstallItems: installItems ?? explicitInstallItems,
|
|
877
|
+
announceDownload: false,
|
|
878
|
+
});
|
|
911
879
|
}
|
|
912
880
|
|
|
913
881
|
if (!bootloaderBinary && fwBinaryMap.length === 0 && !installItems?.length) {
|
|
@@ -1060,133 +1028,69 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1060
1028
|
return installSources;
|
|
1061
1029
|
}
|
|
1062
1030
|
|
|
1063
|
-
private async
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
availableInstallItems = this.buildProtocolV2InstallItems({
|
|
1067
|
-
bootloaderBinary: this.prepareBootloaderBinary(),
|
|
1068
|
-
fwBinaryMap: this.collectExplicitTargetBinaries(),
|
|
1069
|
-
}),
|
|
1031
|
+
private async runProtocolV2DirectArtifacts({
|
|
1032
|
+
availableInstallItems,
|
|
1033
|
+
announceDownload = true,
|
|
1070
1034
|
}: {
|
|
1071
|
-
features: Features;
|
|
1072
|
-
firmwareType: EFirmwareType;
|
|
1073
1035
|
availableInstallItems?: ProtocolV2InstallItem[];
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
);
|
|
1087
|
-
const missingTarget = Array.from(requestedComponentTargets).find(
|
|
1088
|
-
target => !localComponentTargets.has(target)
|
|
1089
|
-
);
|
|
1090
|
-
if (missingTarget) {
|
|
1091
|
-
throw ERRORS.TypedError(
|
|
1092
|
-
HardwareErrorCode.RuntimeError,
|
|
1093
|
-
`Protocol V2 local update has no binary for requested target ${missingTarget}`,
|
|
1094
|
-
{
|
|
1095
|
-
firmwareUpdateCode: 'FirmwareArtifactsNotPrepared',
|
|
1096
|
-
artifactName: missingTarget,
|
|
1097
|
-
}
|
|
1036
|
+
announceDownload?: boolean;
|
|
1037
|
+
}) {
|
|
1038
|
+
try {
|
|
1039
|
+
if (announceDownload) {
|
|
1040
|
+
this.postTipMessage(FirmwareUpdateTipMessage.StartDownloadFirmware);
|
|
1041
|
+
}
|
|
1042
|
+
const installItems = this.filterProtocolV2LocalInstallItems(
|
|
1043
|
+
availableInstallItems ??
|
|
1044
|
+
this.buildProtocolV2InstallItems({
|
|
1045
|
+
bootloaderBinary: this.prepareBootloaderBinary(),
|
|
1046
|
+
fwBinaryMap: this.collectExplicitTargetBinaries(),
|
|
1047
|
+
})
|
|
1098
1048
|
);
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1049
|
+
const installSources = await Promise.all(
|
|
1050
|
+
installItems.map(async item => ({
|
|
1051
|
+
fileName: item.fileName,
|
|
1052
|
+
source: await this.openProtocolV2MemorySource(item.binary),
|
|
1053
|
+
targetId: item.targetId,
|
|
1054
|
+
kind: item.kind,
|
|
1055
|
+
}))
|
|
1056
|
+
);
|
|
1057
|
+
const resourceSources = this.params.resourceArchiveBinary
|
|
1058
|
+
? await this.createProtocolV2ResourceSourcesFromArchive(this.params.resourceArchiveBinary)
|
|
1059
|
+
: [];
|
|
1060
|
+
if (installSources.length === 0 && resourceSources.length === 0) {
|
|
1108
1061
|
throw ERRORS.TypedError(
|
|
1109
|
-
HardwareErrorCode.
|
|
1110
|
-
|
|
1111
|
-
{ firmwareUpdateCode: 'FirmwareArtifactsNotPrepared' }
|
|
1062
|
+
HardwareErrorCode.FirmwareUpdateDownloadFailed,
|
|
1063
|
+
'No firmware to update'
|
|
1112
1064
|
);
|
|
1113
1065
|
}
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
expectedSize: item.binary.byteLength,
|
|
1121
|
-
expectedSha256: bytesToHex(sha256(new Uint8Array(item.binary))),
|
|
1122
|
-
...(this.params.expectedTargetVersions?.[target]
|
|
1123
|
-
? { targetVersion: this.params.expectedTargetVersions[target] }
|
|
1124
|
-
: {}),
|
|
1066
|
+
if (announceDownload) {
|
|
1067
|
+
this.postTipMessage(FirmwareUpdateTipMessage.FinishDownloadFirmware);
|
|
1068
|
+
}
|
|
1069
|
+
return await this.executeProtocolV2SourceUpdate({
|
|
1070
|
+
installSources,
|
|
1071
|
+
resourceSources,
|
|
1125
1072
|
});
|
|
1126
|
-
|
|
1073
|
+
} finally {
|
|
1074
|
+
await this.closeProtocolV2PreparedSources();
|
|
1127
1075
|
}
|
|
1076
|
+
}
|
|
1128
1077
|
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
const
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
artifactId: resourceArtifactId,
|
|
1143
|
-
binary: resourceArchive.binary,
|
|
1144
|
-
materializedEntries: resourceArchive.materializedEntries,
|
|
1145
|
-
});
|
|
1146
|
-
|
|
1147
|
-
const plan = buildProtocolV2LocalFirmwareUpdatePlan({
|
|
1148
|
-
features,
|
|
1149
|
-
firmwareType,
|
|
1150
|
-
platform: this.params.platform,
|
|
1151
|
-
artifacts: planArtifacts,
|
|
1152
|
-
});
|
|
1153
|
-
let memoryHost: FirmwareUpdateV4MemoryHost | undefined;
|
|
1154
|
-
try {
|
|
1155
|
-
memoryHost = prepareFirmwareUpdateV4MemoryHost({
|
|
1156
|
-
sdk: {
|
|
1157
|
-
prepareFirmwareUpdatePlan,
|
|
1158
|
-
registerFirmwareUpdateHostBinding,
|
|
1159
|
-
unregisterFirmwareUpdateHostBinding,
|
|
1160
|
-
},
|
|
1161
|
-
plan,
|
|
1162
|
-
artifacts: memoryArtifacts,
|
|
1163
|
-
});
|
|
1164
|
-
const preparedPlan = validateFirmwareUpdatePreparedPlan(memoryHost.preparedPlan);
|
|
1165
|
-
assertFirmwareUpdatePreparedPlanBinding({
|
|
1166
|
-
preparedPlan,
|
|
1167
|
-
executor: 'v4',
|
|
1168
|
-
platform: this.params.platform,
|
|
1169
|
-
scopeTargets: [],
|
|
1170
|
-
bindings: [],
|
|
1171
|
-
});
|
|
1172
|
-
assertFirmwareUpdatePreparedPlanDeviceIdentity({
|
|
1173
|
-
preparedPlan,
|
|
1174
|
-
deviceIdentity: this.protocolV2ExpectedSerialNumber,
|
|
1175
|
-
deviceModel: this.getProtocolV2PreparedPlanDeviceModel(features),
|
|
1078
|
+
private async createProtocolV2ResourceSourcesFromArchive(
|
|
1079
|
+
binary: ArrayBuffer
|
|
1080
|
+
): Promise<ProtocolV2ResourceBundleSource[]> {
|
|
1081
|
+
const archive = await this.prepareProtocolV2LocalResourceArchive(binary);
|
|
1082
|
+
const sources: ProtocolV2ResourceBundleSource[] = [];
|
|
1083
|
+
for (const resource of archive.resources) {
|
|
1084
|
+
sources.push({
|
|
1085
|
+
name: resource.entryName.split('/').pop() ?? resource.entryName,
|
|
1086
|
+
source: await this.openProtocolV2MemorySource(resource.binary),
|
|
1087
|
+
devicePath: resource.header.devicePath,
|
|
1088
|
+
version: resource.header.version,
|
|
1089
|
+
payloadHash: resource.header.payloadHash,
|
|
1090
|
+
headerHash: resource.header.headerHash,
|
|
1176
1091
|
});
|
|
1177
|
-
const hostBinding = resolveFirmwareUpdateHostBinding(
|
|
1178
|
-
memoryHost.hostBindingGeneration,
|
|
1179
|
-
preparedPlan.preparedPlanDigest
|
|
1180
|
-
);
|
|
1181
|
-
this.params.preparedPlan = preparedPlan;
|
|
1182
|
-
this.params.targetsToUpdate = [...preparedPlan.targetsToUpdate] as FirmwareUpdateV4Target[];
|
|
1183
|
-
this.params.artifactReader = hostBinding.artifactReader;
|
|
1184
|
-
this.params.componentArtifacts = undefined;
|
|
1185
|
-
return memoryHost;
|
|
1186
|
-
} catch (error) {
|
|
1187
|
-
memoryHost?.release();
|
|
1188
|
-
throw error;
|
|
1189
1092
|
}
|
|
1093
|
+
return sources;
|
|
1190
1094
|
}
|
|
1191
1095
|
|
|
1192
1096
|
private async prepareProtocolV2LocalResourceArchive(
|
|
@@ -1225,7 +1129,6 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1225
1129
|
}
|
|
1226
1130
|
|
|
1227
1131
|
let totalSize = 0;
|
|
1228
|
-
const materializedEntries: FirmwareMemoryArtifactEntry[] = [];
|
|
1229
1132
|
const resources: ProtocolV2LocalResourceArchive['resources'] = [];
|
|
1230
1133
|
const devicePaths = new Set<string>();
|
|
1231
1134
|
for (const entry of resourceEntries) {
|
|
@@ -1269,10 +1172,9 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1269
1172
|
);
|
|
1270
1173
|
}
|
|
1271
1174
|
devicePaths.add(canonicalDevicePath);
|
|
1272
|
-
materializedEntries.push({ entryName: entry.name, binary: fileBinary });
|
|
1273
1175
|
resources.push({ entryName: entry.name, binary: fileBinary, header });
|
|
1274
1176
|
}
|
|
1275
|
-
return { binary,
|
|
1177
|
+
return { binary, resources };
|
|
1276
1178
|
}
|
|
1277
1179
|
|
|
1278
1180
|
private async prepareProtocolV2ResourceSources(): Promise<ProtocolV2ResourceBundleSource[]> {
|
|
@@ -1339,20 +1241,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1339
1241
|
|
|
1340
1242
|
// The verified ZIP bytes are authoritative. Non-okpkg entries are release
|
|
1341
1243
|
// metadata only; each RESOURCE package carries its own device path.
|
|
1342
|
-
|
|
1343
|
-
const sources: ProtocolV2ResourceBundleSource[] = [];
|
|
1344
|
-
for (const resource of verifiedArchive.resources) {
|
|
1345
|
-
const source = await this.openProtocolV2MemorySource(resource.binary);
|
|
1346
|
-
sources.push({
|
|
1347
|
-
name: resource.entryName.split('/').pop() ?? resource.entryName,
|
|
1348
|
-
source,
|
|
1349
|
-
devicePath: resource.header.devicePath,
|
|
1350
|
-
version: resource.header.version,
|
|
1351
|
-
payloadHash: resource.header.payloadHash,
|
|
1352
|
-
headerHash: resource.header.headerHash,
|
|
1353
|
-
});
|
|
1354
|
-
}
|
|
1355
|
-
return sources;
|
|
1244
|
+
return this.createProtocolV2ResourceSourcesFromArchive(archiveBinary);
|
|
1356
1245
|
}
|
|
1357
1246
|
|
|
1358
1247
|
private async runProtocolV2PreparedArtifacts(
|
|
@@ -1836,6 +1725,12 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1836
1725
|
return `vol0:/${path}`;
|
|
1837
1726
|
}
|
|
1838
1727
|
|
|
1728
|
+
private getProtocolV2ResourceComparePath(devicePath: string) {
|
|
1729
|
+
return isProtocolV2BootResourcePackagePath(devicePath)
|
|
1730
|
+
? PROTOCOL_V2_BOOT_RESOURCE_PACKAGE_PATH
|
|
1731
|
+
: devicePath;
|
|
1732
|
+
}
|
|
1733
|
+
|
|
1839
1734
|
private async readProtocolV2DeviceFileHeader(path: string, expectedSize?: number) {
|
|
1840
1735
|
const typedCall = this.device.getCommands().typedCall.bind(this.device.getCommands());
|
|
1841
1736
|
const filePath = this.getProtocolV2ResourceFilePath(path);
|
|
@@ -1898,7 +1793,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1898
1793
|
|
|
1899
1794
|
try {
|
|
1900
1795
|
const header = await this.readProtocolV2DeviceFileHeader(
|
|
1901
|
-
bundle.devicePath,
|
|
1796
|
+
this.getProtocolV2ResourceComparePath(bundle.devicePath),
|
|
1902
1797
|
bundle.source.size
|
|
1903
1798
|
);
|
|
1904
1799
|
if (!header) return false;
|
|
@@ -2157,11 +2052,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2157
2052
|
let totalSize = installSources.reduce((total, item) => total + item.source.size, 0);
|
|
2158
2053
|
const resourcesToSync: ProtocolV2ResourceBundleSource[] = [];
|
|
2159
2054
|
for (const resource of resourceSources) {
|
|
2160
|
-
|
|
2161
|
-
// stale staging bytes with the artifact approved by the current PreparedPlan,
|
|
2162
|
-
// even when the mounted final file itself is already current.
|
|
2163
|
-
const requiresFreshStaging = isProtocolV2BootResourcePackagePath(resource.devicePath);
|
|
2164
|
-
if (!requiresFreshStaging && (await this.isProtocolV2ResourceBundleUpToDate(resource))) {
|
|
2055
|
+
if (await this.isProtocolV2ResourceBundleUpToDate(resource)) {
|
|
2165
2056
|
Log.log(`[FirmwareUpdateV4] skip RESC bundle ${resource.name}; already up to date`);
|
|
2166
2057
|
} else {
|
|
2167
2058
|
resourcesToSync.push(resource);
|
|
@@ -654,47 +654,6 @@ const finalizeFirmwareUpdatePlan = ({
|
|
|
654
654
|
});
|
|
655
655
|
};
|
|
656
656
|
|
|
657
|
-
export type ProtocolV2LocalFirmwareUpdatePlanArtifact = {
|
|
658
|
-
artifactId: string;
|
|
659
|
-
target: Exclude<FirmwareUpdateV4Target, 'boot_resources'>;
|
|
660
|
-
container: 'raw' | 'zip';
|
|
661
|
-
logicalName: string;
|
|
662
|
-
expectedSize: number;
|
|
663
|
-
expectedSha256: string;
|
|
664
|
-
targetVersion?: string;
|
|
665
|
-
};
|
|
666
|
-
|
|
667
|
-
export const buildProtocolV2LocalFirmwareUpdatePlan = ({
|
|
668
|
-
features,
|
|
669
|
-
firmwareType,
|
|
670
|
-
platform,
|
|
671
|
-
artifacts,
|
|
672
|
-
}: {
|
|
673
|
-
features: Features;
|
|
674
|
-
firmwareType: EFirmwareType;
|
|
675
|
-
platform: FirmwareUpdatePlatform;
|
|
676
|
-
artifacts: ProtocolV2LocalFirmwareUpdatePlanArtifact[];
|
|
677
|
-
}): FirmwareUpdatePlan => {
|
|
678
|
-
if (artifacts.length === 0) {
|
|
679
|
-
return planError('Protocol V2 local firmware plan has no artifacts');
|
|
680
|
-
}
|
|
681
|
-
const plan = finalizeFirmwareUpdatePlan({
|
|
682
|
-
features,
|
|
683
|
-
firmwareType,
|
|
684
|
-
platform,
|
|
685
|
-
artifacts: artifacts.map(artifact => ({
|
|
686
|
-
...artifact,
|
|
687
|
-
role: artifact.target === 'resource' ? 'resourceBundle' : 'component',
|
|
688
|
-
url: `https://local-firmware.invalid/${encodeURIComponent(artifact.artifactId)}`,
|
|
689
|
-
})),
|
|
690
|
-
targetsToUpdate: artifacts.map(artifact => artifact.target),
|
|
691
|
-
});
|
|
692
|
-
if (plan.executor !== 'v4') {
|
|
693
|
-
return planError('Protocol V2 local firmware plan requires executor v4');
|
|
694
|
-
}
|
|
695
|
-
return plan;
|
|
696
|
-
};
|
|
697
|
-
|
|
698
657
|
export const buildProtocolV2FirmwareUpdatePlan = ({
|
|
699
658
|
features,
|
|
700
659
|
firmwareType,
|
|
@@ -73,6 +73,8 @@ export const getFirmwareUpdateResourceName = (value: unknown): string => {
|
|
|
73
73
|
|
|
74
74
|
const getPreparedEntryIdentity = (entryName: unknown): string => {
|
|
75
75
|
getFirmwareUpdateResourceName(entryName);
|
|
76
|
+
// Protocol V2 resource ZIPs can ship the same basename from different
|
|
77
|
+
// directories, such as rom/params.okpkg and bootloader/params.okpkg.
|
|
76
78
|
return (entryName as string).toLowerCase();
|
|
77
79
|
};
|
|
78
80
|
|
|
@@ -69,7 +69,9 @@ export default class TransportManager {
|
|
|
69
69
|
} else if (env === 'desktop-web-ble') {
|
|
70
70
|
await this.transport.init(WebBleLogger, DevicePool.emitter);
|
|
71
71
|
} else if (env === 'webusb' || env === 'desktop-webusb') {
|
|
72
|
-
|
|
72
|
+
// The emitter is what turns a navigator.usb 'disconnect' into a
|
|
73
|
+
// DEVICE.DISCONNECT; without it WebUSB never reports device removal.
|
|
74
|
+
await this.transport.init(WebUsbLogger, DevicePool.emitter);
|
|
73
75
|
} else {
|
|
74
76
|
await this.transport.init(HttpLogger);
|
|
75
77
|
}
|
package/src/index.ts
CHANGED
|
@@ -21,12 +21,6 @@ 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 { prepareFirmwareUpdateV4MemoryHost } from './api/firmware/FirmwareMemoryHost';
|
|
25
|
-
export type {
|
|
26
|
-
FirmwareMemoryArtifact,
|
|
27
|
-
FirmwareMemoryArtifactEntry,
|
|
28
|
-
FirmwareUpdateV4MemoryHost,
|
|
29
|
-
} from './api/firmware/FirmwareMemoryHost';
|
|
30
24
|
export {
|
|
31
25
|
getFirmwareUpdateHostBindingGeneration,
|
|
32
26
|
registerFirmwareUpdateHostBinding,
|
|
@@ -158,7 +158,7 @@ export interface FirmwareUpdateV4Params {
|
|
|
158
158
|
se02Binary?: ArrayBuffer;
|
|
159
159
|
se03Binary?: ArrayBuffer;
|
|
160
160
|
se04Binary?: ArrayBuffer;
|
|
161
|
-
/** Complete Protocol V2 resource ZIP
|
|
161
|
+
/** Complete Protocol V2 resource ZIP. Core parses RESC packages and writes only changed files. */
|
|
162
162
|
resourceArchiveBinary?: ArrayBuffer;
|
|
163
163
|
forcedUpdateRes?: boolean;
|
|
164
164
|
artifactReader?: FirmwareArtifactReader;
|
|
@@ -31,7 +31,9 @@ export const getDeviceTypeByBleName = (name?: string): IDeviceType => {
|
|
|
31
31
|
if (/^Touch/i.test(name)) return EDeviceType.Touch;
|
|
32
32
|
|
|
33
33
|
const compactName = name.replace(/[\s-]/g, '');
|
|
34
|
-
|
|
34
|
+
// Require a 4-hex Pro2 suffix in the compact form. A bare `^Pro2` prefix
|
|
35
|
+
// would also match OneKey Pro names such as "Pro 22D8" / "Pro 2D8F".
|
|
36
|
+
if (/\bPro\s*2\b/i.test(name) || /^(?:OneKey)?Pro2[a-f0-9]{4}$/i.test(compactName)) {
|
|
35
37
|
return EDeviceType.Pro2;
|
|
36
38
|
}
|
|
37
39
|
if (/\bNeo\b/i.test(name) || /^Neo/i.test(name) || /^(?:OneKey)?Neo/i.test(compactName)) {
|
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
import { prepareFirmwareUpdateV4MemoryHost } from '../src/api/firmware/FirmwareMemoryHost';
|
|
2
|
-
|
|
3
|
-
import type { CoreApi } from '../src/types/api';
|
|
4
|
-
import type { FirmwareUpdatePlan } from '../src/types/api/firmwareUpdatePlan';
|
|
5
|
-
|
|
6
|
-
describe('prepareFirmwareUpdateV4MemoryHost', () => {
|
|
7
|
-
test('registers artifact-backed component and resource readers', async () => {
|
|
8
|
-
const componentBinary = new Uint8Array([1, 2, 3, 4]).buffer;
|
|
9
|
-
const archiveBinary = new Uint8Array([5, 6]).buffer;
|
|
10
|
-
const manifestBinary = new TextEncoder().encode('{"schema":1}').buffer;
|
|
11
|
-
let artifactReader: Parameters<
|
|
12
|
-
CoreApi['registerFirmwareUpdateHostBinding']
|
|
13
|
-
>[0]['artifactReader'];
|
|
14
|
-
const unregisterFirmwareUpdateHostBinding = jest.fn();
|
|
15
|
-
const sdk = {
|
|
16
|
-
prepareFirmwareUpdatePlan: jest.fn(({ plan, artifacts }) => ({
|
|
17
|
-
schemaVersion: 2,
|
|
18
|
-
preparedPlanDigest: 'b'.repeat(64),
|
|
19
|
-
planDigest: plan.planDigest,
|
|
20
|
-
networkPolicy: 'forbid',
|
|
21
|
-
executor: plan.executor,
|
|
22
|
-
deviceIdentity: plan.deviceIdentity,
|
|
23
|
-
deviceModel: plan.deviceModel,
|
|
24
|
-
firmwareType: plan.firmwareType,
|
|
25
|
-
platform: plan.platform,
|
|
26
|
-
leaseRef: 'test-lease',
|
|
27
|
-
targetsToUpdate: plan.targetsToUpdate,
|
|
28
|
-
artifacts: plan.artifacts.map(planArtifact => {
|
|
29
|
-
const input = artifacts.find(item => item.artifactId === planArtifact.artifactId);
|
|
30
|
-
return {
|
|
31
|
-
...planArtifact,
|
|
32
|
-
artifact: input?.artifact,
|
|
33
|
-
materializedEntries: input?.materializedEntries,
|
|
34
|
-
};
|
|
35
|
-
}),
|
|
36
|
-
})),
|
|
37
|
-
registerFirmwareUpdateHostBinding: jest.fn(binding => {
|
|
38
|
-
artifactReader = binding.artifactReader;
|
|
39
|
-
return 7;
|
|
40
|
-
}),
|
|
41
|
-
unregisterFirmwareUpdateHostBinding,
|
|
42
|
-
} as unknown as Pick<
|
|
43
|
-
CoreApi,
|
|
44
|
-
| 'prepareFirmwareUpdatePlan'
|
|
45
|
-
| 'registerFirmwareUpdateHostBinding'
|
|
46
|
-
| 'unregisterFirmwareUpdateHostBinding'
|
|
47
|
-
>;
|
|
48
|
-
const plan = {
|
|
49
|
-
schemaVersion: 2,
|
|
50
|
-
planDigest: 'a'.repeat(64),
|
|
51
|
-
executor: 'v4',
|
|
52
|
-
deviceIdentity: 'device-id',
|
|
53
|
-
deviceModel: 'pro2',
|
|
54
|
-
firmwareType: 0,
|
|
55
|
-
platform: 'web',
|
|
56
|
-
targetsToUpdate: ['boot', 'resource'],
|
|
57
|
-
artifacts: [
|
|
58
|
-
{
|
|
59
|
-
artifactId: 'component:boot',
|
|
60
|
-
role: 'component',
|
|
61
|
-
target: 'boot',
|
|
62
|
-
url: 'https://example.com/boot.okpkg',
|
|
63
|
-
container: 'raw',
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
artifactId: 'resource:archive',
|
|
67
|
-
role: 'resourceBundle',
|
|
68
|
-
target: 'resource',
|
|
69
|
-
url: 'https://example.com/resource.zip',
|
|
70
|
-
container: 'zip',
|
|
71
|
-
logicalName: 'resource-archive',
|
|
72
|
-
},
|
|
73
|
-
],
|
|
74
|
-
} as FirmwareUpdatePlan;
|
|
75
|
-
|
|
76
|
-
const host = prepareFirmwareUpdateV4MemoryHost({
|
|
77
|
-
sdk,
|
|
78
|
-
plan,
|
|
79
|
-
artifacts: [
|
|
80
|
-
{ artifactId: 'component:boot', binary: componentBinary },
|
|
81
|
-
{
|
|
82
|
-
artifactId: 'resource:archive',
|
|
83
|
-
binary: archiveBinary,
|
|
84
|
-
materializedEntries: [{ entryName: 'manifest.json', binary: manifestBinary }],
|
|
85
|
-
},
|
|
86
|
-
],
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
expect(host.hostBindingGeneration).toBe(7);
|
|
90
|
-
expect(sdk.registerFirmwareUpdateHostBinding).toHaveBeenCalledWith(
|
|
91
|
-
expect.objectContaining({ preparedPlanDigest: host.preparedPlan.preparedPlanDigest })
|
|
92
|
-
);
|
|
93
|
-
const componentArtifact = host.preparedPlan.artifacts.find(
|
|
94
|
-
artifact => artifact.target === 'boot'
|
|
95
|
-
)?.artifact;
|
|
96
|
-
const resourceEntryArtifact = host.preparedPlan.artifacts.find(
|
|
97
|
-
artifact => artifact.target === 'resource'
|
|
98
|
-
)?.materializedEntries?.[0]?.artifact;
|
|
99
|
-
expect(componentArtifact?.size).toBe(componentBinary.byteLength);
|
|
100
|
-
expect(resourceEntryArtifact?.size).toBe(manifestBinary.byteLength);
|
|
101
|
-
if (!artifactReader || !componentArtifact || !resourceEntryArtifact) {
|
|
102
|
-
throw new Error('Firmware memory host test setup is incomplete');
|
|
103
|
-
}
|
|
104
|
-
new Uint8Array(componentBinary).fill(9);
|
|
105
|
-
const opened = await artifactReader.open({
|
|
106
|
-
artifactRef: componentArtifact.artifactRef,
|
|
107
|
-
});
|
|
108
|
-
const chunk = await artifactReader.read({
|
|
109
|
-
readerId: opened.readerId,
|
|
110
|
-
offset: 1,
|
|
111
|
-
length: 2,
|
|
112
|
-
});
|
|
113
|
-
expect(Array.from(new Uint8Array(chunk.data))).toEqual([2, 3]);
|
|
114
|
-
await artifactReader.close({ readerId: opened.readerId });
|
|
115
|
-
|
|
116
|
-
// Materialized ZIP entries are receipts only. Execution opens the approved
|
|
117
|
-
// archive and re-derives these bytes, so the memory host must not retain a
|
|
118
|
-
// second readable copy of every expanded resource file.
|
|
119
|
-
expect(() => artifactReader.open({ artifactRef: resourceEntryArtifact.artifactRef })).toThrow(
|
|
120
|
-
'Firmware memory artifact is unavailable'
|
|
121
|
-
);
|
|
122
|
-
|
|
123
|
-
host.release();
|
|
124
|
-
expect(unregisterFirmwareUpdateHostBinding).toHaveBeenCalledWith(7);
|
|
125
|
-
});
|
|
126
|
-
});
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import type { CoreApi } from '../../types/api';
|
|
2
|
-
import type { FirmwareUpdatePlan } from '../../types/api/firmwareUpdatePlan';
|
|
3
|
-
export type FirmwareMemoryArtifactEntry = {
|
|
4
|
-
entryName: string;
|
|
5
|
-
binary: ArrayBuffer;
|
|
6
|
-
};
|
|
7
|
-
export type FirmwareMemoryArtifact = {
|
|
8
|
-
artifactId: string;
|
|
9
|
-
binary: ArrayBuffer;
|
|
10
|
-
materializedEntries?: FirmwareMemoryArtifactEntry[];
|
|
11
|
-
};
|
|
12
|
-
export type FirmwareUpdateV4MemoryHost = {
|
|
13
|
-
preparedPlan: ReturnType<CoreApi['prepareFirmwareUpdatePlan']>;
|
|
14
|
-
hostBindingGeneration: number;
|
|
15
|
-
release: () => void;
|
|
16
|
-
};
|
|
17
|
-
export declare function prepareFirmwareUpdateV4MemoryHost({ sdk, plan, artifacts, }: {
|
|
18
|
-
sdk: Pick<CoreApi, 'prepareFirmwareUpdatePlan' | 'registerFirmwareUpdateHostBinding' | 'unregisterFirmwareUpdateHostBinding'>;
|
|
19
|
-
plan: FirmwareUpdatePlan;
|
|
20
|
-
artifacts: FirmwareMemoryArtifact[];
|
|
21
|
-
}): FirmwareUpdateV4MemoryHost;
|
|
22
|
-
//# sourceMappingURL=FirmwareMemoryHost.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"FirmwareMemoryHost.d.ts","sourceRoot":"","sources":["../../../src/api/firmware/FirmwareMemoryHost.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAK/C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAE7E,MAAM,MAAM,2BAA2B,GAAG;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,WAAW,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,WAAW,CAAC;IACpB,mBAAmB,CAAC,EAAE,2BAA2B,EAAE,CAAC;CACrD,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,YAAY,EAAE,UAAU,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAC,CAAC;IAC/D,qBAAqB,EAAE,MAAM,CAAC;IAC9B,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAaF,wBAAgB,iCAAiC,CAAC,EAChD,GAAG,EACH,IAAI,EACJ,SAAS,GACV,EAAE;IACD,GAAG,EAAE,IAAI,CACP,OAAO,EACL,2BAA2B,GAC3B,mCAAmC,GACnC,qCAAqC,CACxC,CAAC;IACF,IAAI,EAAE,kBAAkB,CAAC;IACzB,SAAS,EAAE,sBAAsB,EAAE,CAAC;CACrC,GAAG,0BAA0B,CA0F7B"}
|