@onekeyfe/hd-core 1.2.2-alpha.6 → 1.2.2-alpha.7
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 +14 -0
- package/__tests__/pro2HostAssetPackage.test.ts +108 -1
- package/__tests__/protocol-v2.test.ts +129 -19
- package/__tests__/protocolV2FileWrite.test.ts +40 -0
- package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
- package/dist/api/helpers/protocolV2FileWrite.d.ts +1 -0
- package/dist/api/helpers/protocolV2FileWrite.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts.map +1 -1
- package/dist/core/index.d.ts +2 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/index.js +107 -41
- package/dist/utils/pro2HostAssetPackage.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/api/FirmwareUpdateV4.ts +33 -6
- package/src/api/helpers/protocolV2FileWrite.ts +11 -5
- package/src/api/protocol-v2/DeviceUploadWallpaper.ts +8 -2
- package/src/core/index.ts +19 -8
- package/src/utils/pro2HostAssetPackage.ts +73 -27
package/dist/index.js
CHANGED
|
@@ -52094,11 +52094,15 @@ function isProtocolV2ResponseTimeout(error) {
|
|
|
52094
52094
|
code === 'response-timeout' ||
|
|
52095
52095
|
/(?:BLE|Lowlevel|Protocol V2) response timeout/i.test((_b = candidate.message) !== null && _b !== void 0 ? _b : ''));
|
|
52096
52096
|
}
|
|
52097
|
-
function getProtocolV2FileChunkLimit() {
|
|
52097
|
+
function getProtocolV2FileChunkLimit(bleChunkSizeLimit) {
|
|
52098
52098
|
const env = DataManager.getSettings('env');
|
|
52099
|
-
|
|
52100
|
-
|
|
52101
|
-
|
|
52099
|
+
if (env && DataManager.isBleConnect(env)) {
|
|
52100
|
+
const configuredLimit = Number(bleChunkSizeLimit);
|
|
52101
|
+
return Number.isFinite(configuredLimit) && configuredLimit > 0
|
|
52102
|
+
? Math.floor(configuredLimit)
|
|
52103
|
+
: hdTransport.PROTOCOL_V2_BLE_FILE_CHUNK_SIZE;
|
|
52104
|
+
}
|
|
52105
|
+
return hdTransport.PROTOCOL_V2_WEBUSB_FILE_CHUNK_SIZE;
|
|
52102
52106
|
}
|
|
52103
52107
|
function dataToUint8Array(data) {
|
|
52104
52108
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -52153,7 +52157,7 @@ function writeProtocolV2File(options) {
|
|
|
52153
52157
|
if (totalSize < startOffset + dataLength) {
|
|
52154
52158
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.RuntimeError, `FilesystemFileWrite totalSize ${totalSize} is smaller than offset + data length ${startOffset + dataLength}`);
|
|
52155
52159
|
}
|
|
52156
|
-
const defaultChunkSizeLimit = getProtocolV2FileChunkLimit();
|
|
52160
|
+
const defaultChunkSizeLimit = getProtocolV2FileChunkLimit(options.bleChunkSizeLimit);
|
|
52157
52161
|
const configuredChunkSizeLimit = Number(options.chunkSizeLimit);
|
|
52158
52162
|
const chunkSizeLimit = Number.isFinite(configuredChunkSizeLimit) && configuredChunkSizeLimit > 0
|
|
52159
52163
|
? Math.floor(configuredChunkSizeLimit)
|
|
@@ -52504,6 +52508,13 @@ const isProtocolV2InstallResponseTimeout = (error) => {
|
|
|
52504
52508
|
return (code === 'response-timeout' ||
|
|
52505
52509
|
/\bresponse timeout\b/i.test(getProtocolV2UnknownErrorText(error)));
|
|
52506
52510
|
};
|
|
52511
|
+
const getProtocolV2ErrorCode = (error) => {
|
|
52512
|
+
if (!error || typeof error !== 'object')
|
|
52513
|
+
return undefined;
|
|
52514
|
+
const { errorCode, code } = error;
|
|
52515
|
+
const causeCode = errorCode !== null && errorCode !== void 0 ? errorCode : code;
|
|
52516
|
+
return typeof causeCode === 'number' || typeof causeCode === 'string' ? causeCode : undefined;
|
|
52517
|
+
};
|
|
52507
52518
|
const isProtocolV2TerminalInstallStatusError = (error) => {
|
|
52508
52519
|
var _a;
|
|
52509
52520
|
return hdShared.isBleStaleBondHardwareError(error) ||
|
|
@@ -53796,6 +53807,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
53796
53807
|
this.postTipMessage(exports.FirmwareUpdateTipMessage.StartTransferData);
|
|
53797
53808
|
this.protocolV2LastTransferProgress = undefined;
|
|
53798
53809
|
this.protocolV2LastTransferProgressAt = 0;
|
|
53810
|
+
const transferStartedAt = Date.now();
|
|
53799
53811
|
let processedSize = 0;
|
|
53800
53812
|
for (const resource of resourcesToSync) {
|
|
53801
53813
|
const writePath = resource.devicePath;
|
|
@@ -53804,6 +53816,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
53804
53816
|
filePath: writePath,
|
|
53805
53817
|
processedSize,
|
|
53806
53818
|
totalSize,
|
|
53819
|
+
transferStartedAt,
|
|
53807
53820
|
});
|
|
53808
53821
|
yield this.verifyProtocolV2StagedFile(writePath, resource.source.size);
|
|
53809
53822
|
if (isProtocolV2BootResourcePackagePath(resource.devicePath)) {
|
|
@@ -53818,6 +53831,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
53818
53831
|
filePath,
|
|
53819
53832
|
processedSize,
|
|
53820
53833
|
totalSize,
|
|
53834
|
+
transferStartedAt,
|
|
53821
53835
|
});
|
|
53822
53836
|
yield this.verifyProtocolV2StagedFile(filePath, item.source.size);
|
|
53823
53837
|
stagedInstallTargets.push({
|
|
@@ -53826,7 +53840,13 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
53826
53840
|
});
|
|
53827
53841
|
}
|
|
53828
53842
|
if (totalSize > 0) {
|
|
53829
|
-
|
|
53843
|
+
const elapsedMs = Math.max(Date.now() - transferStartedAt, 0);
|
|
53844
|
+
this.postProgressMessage(100, 'transferData', {
|
|
53845
|
+
transferredBytes: totalSize,
|
|
53846
|
+
totalBytes: totalSize,
|
|
53847
|
+
rateBytesPerSecond: elapsedMs > 0 ? Math.round((totalSize / elapsedMs) * 1000) : undefined,
|
|
53848
|
+
elapsedMs,
|
|
53849
|
+
});
|
|
53830
53850
|
}
|
|
53831
53851
|
if (stagedInstallTargets.length === 0) {
|
|
53832
53852
|
return;
|
|
@@ -53846,16 +53866,17 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
53846
53866
|
}
|
|
53847
53867
|
});
|
|
53848
53868
|
}
|
|
53849
|
-
protocolV2SourceUpdateProcess({ source, filePath, processedSize, totalSize, }) {
|
|
53869
|
+
protocolV2SourceUpdateProcess({ source, filePath, processedSize, totalSize, transferStartedAt = Date.now(), }) {
|
|
53850
53870
|
return __awaiter(this, void 0, void 0, function* () {
|
|
53851
53871
|
let lastError;
|
|
53852
53872
|
for (let attempt = 1; attempt <= PROTOCOL_V2_FILE_TRANSFER_RETRY_COUNT; attempt += 1) {
|
|
53873
|
+
this.throwIfAborted();
|
|
53853
53874
|
try {
|
|
53854
|
-
const transferStartedAt = Date.now();
|
|
53855
53875
|
yield writeFirmwareByteSource({
|
|
53856
53876
|
source,
|
|
53857
53877
|
chunkSize: this.getProtocolV2FirmwareChunkSize('write', filePath),
|
|
53858
53878
|
write: ({ data, sourceOffset, length, first }) => __awaiter(this, void 0, void 0, function* () {
|
|
53879
|
+
this.throwIfAborted();
|
|
53859
53880
|
const chunkEnd = sourceOffset + length;
|
|
53860
53881
|
const deviceProgress = getProtocolV2DeviceTransferProgress(processedSize + sourceOffset, processedSize + chunkEnd, totalSize);
|
|
53861
53882
|
const response = yield this.fileWriteChunk(filePath, source.size, sourceOffset, data, first, deviceProgress);
|
|
@@ -53878,7 +53899,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
53878
53899
|
this.postProgressMessage(progress, 'transferData', {
|
|
53879
53900
|
transferredBytes,
|
|
53880
53901
|
totalBytes: totalSize,
|
|
53881
|
-
rateBytesPerSecond: elapsedMs > 0 ? Math.round((
|
|
53902
|
+
rateBytesPerSecond: elapsedMs > 0 ? Math.round((transferredBytes / elapsedMs) * 1000) : undefined,
|
|
53882
53903
|
elapsedMs,
|
|
53883
53904
|
});
|
|
53884
53905
|
}
|
|
@@ -53888,16 +53909,19 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
53888
53909
|
return processedSize + source.size;
|
|
53889
53910
|
}
|
|
53890
53911
|
catch (error) {
|
|
53912
|
+
this.throwIfAborted();
|
|
53891
53913
|
if (hdShared.isBleStaleBondHardwareError(error)) {
|
|
53892
53914
|
throw error;
|
|
53893
53915
|
}
|
|
53894
53916
|
lastError = error;
|
|
53895
53917
|
if (attempt < PROTOCOL_V2_FILE_TRANSFER_RETRY_COUNT) {
|
|
53896
53918
|
yield this.recoverProtocolV2FileTransfer();
|
|
53919
|
+
this.throwIfAborted();
|
|
53897
53920
|
}
|
|
53898
53921
|
}
|
|
53899
53922
|
}
|
|
53900
|
-
|
|
53923
|
+
const causeCode = getProtocolV2ErrorCode(lastError);
|
|
53924
|
+
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.EmmcFileWriteFirmwareError, `transfer data error: ${getProtocolV2UnknownErrorText(lastError)}`, causeCode === undefined ? undefined : { causeCode });
|
|
53901
53925
|
});
|
|
53902
53926
|
}
|
|
53903
53927
|
getProtocolV2InstallItemStagingPath(item) {
|
|
@@ -54244,7 +54268,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
54244
54268
|
return;
|
|
54245
54269
|
}
|
|
54246
54270
|
if (!hasCurrentInstallEvidence) {
|
|
54247
|
-
this.device.setCancelableAction(() =>
|
|
54271
|
+
this.device.setCancelableAction(() => Promise.resolve());
|
|
54248
54272
|
}
|
|
54249
54273
|
if (requireCurrentInstallStatus &&
|
|
54250
54274
|
!hasCurrentInstallEvidence &&
|
|
@@ -54590,7 +54614,7 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
|
|
|
54590
54614
|
this.protocolV2InstallTerminalSuccessObserved = false;
|
|
54591
54615
|
const commands = this.device.getCommands();
|
|
54592
54616
|
yield commands.typedCall('DeviceFirmwareUpdateStage', 'Success', { targets });
|
|
54593
|
-
this.device.setCancelableAction(() =>
|
|
54617
|
+
this.device.setCancelableAction(() => Promise.resolve());
|
|
54594
54618
|
const interaction = this.device.createProtocolV2UiPhaseMetadata('button', 'start');
|
|
54595
54619
|
this.postMessage(createUiMessage(UI_REQUEST.REQUEST_BUTTON, Object.assign({ device: this.device.toMessageObject(), source: 'method-lifecycle', reason: 'firmware-update', completion: 'operation-completed', deviceOnly: true, operation: this.name }, (interaction ? { interaction } : {}))));
|
|
54596
54620
|
try {
|
|
@@ -54824,7 +54848,9 @@ const ARCHIVE_ENTRY_SIZE = 296;
|
|
|
54824
54848
|
const ARCHIVE_ENTRY_NAME_MAX_LENGTH = 255;
|
|
54825
54849
|
const ARCHIVE_COMPRESS_LZ4_BLOCKED = 1;
|
|
54826
54850
|
const ARCHIVE_ALIGNMENT = 4;
|
|
54827
|
-
const
|
|
54851
|
+
const LZ4_PREFERRED_BLOCK_SIZE_LOG2 = 14;
|
|
54852
|
+
const LZ4_FALLBACK_BLOCK_SIZE_LOG2 = 13;
|
|
54853
|
+
const LZ4_COMPRESSED_BLOCK_SIZE_MAX = 1 << 14;
|
|
54828
54854
|
function supportsPro2HostAssetPackage(firmwareVersion) {
|
|
54829
54855
|
return Boolean(firmwareVersion &&
|
|
54830
54856
|
semver__default["default"].valid(firmwareVersion) &&
|
|
@@ -54846,7 +54872,7 @@ const LZ4_MAX_OFFSET = 0xffff;
|
|
|
54846
54872
|
const LZ4_LENGTH_MASK = 15;
|
|
54847
54873
|
const LZ4_HASH_LOG = 16;
|
|
54848
54874
|
const LZ4_HASH_MULTIPLIER = 2654435761;
|
|
54849
|
-
const
|
|
54875
|
+
const LZ4_MAX_SEARCH_DEPTH = 64;
|
|
54850
54876
|
function writeExtendedLength(output, offset, length) {
|
|
54851
54877
|
let remaining = length;
|
|
54852
54878
|
let nextOffset = offset;
|
|
@@ -54899,7 +54925,7 @@ function emitLastLiterals(output, outputOffset, input, anchor, literalLength) {
|
|
|
54899
54925
|
}
|
|
54900
54926
|
return copyBytes(output, nextOffset, input, anchor, literalLength);
|
|
54901
54927
|
}
|
|
54902
|
-
function compressRawLz4Block(input, hashTable) {
|
|
54928
|
+
function compressRawLz4Block(input, hashTable, matchChain) {
|
|
54903
54929
|
const output = new Uint8Array(input.byteLength + Math.floor(input.byteLength / 255) + 16);
|
|
54904
54930
|
const inputView = new DataView(input.buffer, input.byteOffset, input.byteLength);
|
|
54905
54931
|
const matchFindLimit = input.byteLength - LZ4_MATCH_FIND_LIMIT;
|
|
@@ -54907,52 +54933,82 @@ function compressRawLz4Block(input, hashTable) {
|
|
|
54907
54933
|
let anchor = 0;
|
|
54908
54934
|
let inputOffset = 0;
|
|
54909
54935
|
let outputOffset = 0;
|
|
54910
|
-
let searchMatchCount = 1 << LZ4_SKIP_TRIGGER;
|
|
54911
54936
|
hashTable.fill(0);
|
|
54912
54937
|
while (inputOffset < matchFindLimit) {
|
|
54913
54938
|
const sequence = inputView.getUint32(inputOffset, true);
|
|
54914
54939
|
const hash = Math.imul(sequence, LZ4_HASH_MULTIPLIER) >>> (32 - LZ4_HASH_LOG);
|
|
54915
|
-
|
|
54940
|
+
let candidate = hashTable[hash] - 1;
|
|
54941
|
+
matchChain[inputOffset] = candidate;
|
|
54916
54942
|
hashTable[hash] = inputOffset + 1;
|
|
54917
|
-
|
|
54918
|
-
|
|
54919
|
-
|
|
54920
|
-
|
|
54921
|
-
inputOffset
|
|
54922
|
-
|
|
54943
|
+
let bestCandidate = -1;
|
|
54944
|
+
let bestMatchEnd = inputOffset;
|
|
54945
|
+
let searchDepth = 0;
|
|
54946
|
+
while (candidate >= 0 &&
|
|
54947
|
+
inputOffset - candidate <= LZ4_MAX_OFFSET &&
|
|
54948
|
+
searchDepth < LZ4_MAX_SEARCH_DEPTH) {
|
|
54949
|
+
if (inputView.getUint32(candidate, true) === sequence) {
|
|
54950
|
+
let matchEnd = inputOffset + LZ4_MIN_MATCH;
|
|
54951
|
+
let reference = candidate + LZ4_MIN_MATCH;
|
|
54952
|
+
while (matchEnd < matchExtendLimit && input[matchEnd] === input[reference]) {
|
|
54953
|
+
matchEnd += 1;
|
|
54954
|
+
reference += 1;
|
|
54955
|
+
}
|
|
54956
|
+
if (matchEnd > bestMatchEnd) {
|
|
54957
|
+
bestCandidate = candidate;
|
|
54958
|
+
bestMatchEnd = matchEnd;
|
|
54959
|
+
}
|
|
54960
|
+
}
|
|
54961
|
+
candidate = matchChain[candidate];
|
|
54962
|
+
searchDepth += 1;
|
|
54963
|
+
}
|
|
54964
|
+
if (bestCandidate < 0) {
|
|
54965
|
+
inputOffset += 1;
|
|
54923
54966
|
}
|
|
54924
54967
|
else {
|
|
54925
|
-
|
|
54926
|
-
|
|
54927
|
-
|
|
54928
|
-
while (matchEnd < matchExtendLimit && input[matchEnd] === input[reference]) {
|
|
54929
|
-
matchEnd += 1;
|
|
54930
|
-
reference += 1;
|
|
54931
|
-
}
|
|
54932
|
-
outputOffset = emitSequence(output, outputOffset, input, anchor, inputOffset - anchor, inputOffset - candidate, matchEnd - inputOffset - LZ4_MIN_MATCH);
|
|
54933
|
-
inputOffset = matchEnd;
|
|
54968
|
+
const matchStart = inputOffset;
|
|
54969
|
+
outputOffset = emitSequence(output, outputOffset, input, anchor, inputOffset - anchor, inputOffset - bestCandidate, bestMatchEnd - inputOffset - LZ4_MIN_MATCH);
|
|
54970
|
+
inputOffset = bestMatchEnd;
|
|
54934
54971
|
anchor = inputOffset;
|
|
54972
|
+
for (let skippedOffset = matchStart + 1; skippedOffset < inputOffset && skippedOffset < matchFindLimit; skippedOffset += 1) {
|
|
54973
|
+
const skippedSequence = inputView.getUint32(skippedOffset, true);
|
|
54974
|
+
const skippedHash = Math.imul(skippedSequence, LZ4_HASH_MULTIPLIER) >>> (32 - LZ4_HASH_LOG);
|
|
54975
|
+
matchChain[skippedOffset] = hashTable[skippedHash] - 1;
|
|
54976
|
+
hashTable[skippedHash] = skippedOffset + 1;
|
|
54977
|
+
}
|
|
54935
54978
|
}
|
|
54936
54979
|
}
|
|
54937
54980
|
outputOffset = emitLastLiterals(output, outputOffset, input, anchor, input.byteLength - anchor);
|
|
54938
54981
|
return output.slice(0, outputOffset);
|
|
54939
54982
|
}
|
|
54940
|
-
function
|
|
54941
|
-
const blockSize = 1 <<
|
|
54983
|
+
function encodeLz4BlockedWithBlockSize(data, blockSizeLog2) {
|
|
54984
|
+
const blockSize = 1 << blockSizeLog2;
|
|
54942
54985
|
const blockCount = Math.ceil(data.byteLength / blockSize);
|
|
54943
54986
|
const hashTable = new Uint32Array(1 << LZ4_HASH_LOG);
|
|
54987
|
+
const matchChain = new Int32Array(blockSize);
|
|
54944
54988
|
const blocks = [];
|
|
54945
54989
|
const header = new Uint8Array(8 + blockCount * 4);
|
|
54946
54990
|
const headerView = new DataView(header.buffer);
|
|
54947
54991
|
headerView.setUint16(0, blockCount, true);
|
|
54948
|
-
headerView.setUint16(2,
|
|
54992
|
+
headerView.setUint16(2, blockSizeLog2, true);
|
|
54949
54993
|
for (let index = 0; index < blockCount; index += 1) {
|
|
54950
|
-
const block = compressRawLz4Block(data.subarray(index * blockSize, Math.min((index + 1) * blockSize, data.byteLength)), hashTable);
|
|
54994
|
+
const block = compressRawLz4Block(data.subarray(index * blockSize, Math.min((index + 1) * blockSize, data.byteLength)), hashTable, matchChain);
|
|
54995
|
+
if (block.byteLength > LZ4_COMPRESSED_BLOCK_SIZE_MAX)
|
|
54996
|
+
return undefined;
|
|
54951
54997
|
headerView.setUint32(8 + index * 4, block.byteLength, true);
|
|
54952
54998
|
blocks.push(block);
|
|
54953
54999
|
}
|
|
54954
55000
|
return concatBytes([header, ...blocks]);
|
|
54955
55001
|
}
|
|
55002
|
+
function encodeLz4Blocked(data) {
|
|
55003
|
+
const preferred = encodeLz4BlockedWithBlockSize(data, LZ4_PREFERRED_BLOCK_SIZE_LOG2);
|
|
55004
|
+
if (preferred)
|
|
55005
|
+
return preferred;
|
|
55006
|
+
const fallback = encodeLz4BlockedWithBlockSize(data, LZ4_FALLBACK_BLOCK_SIZE_LOG2);
|
|
55007
|
+
if (!fallback) {
|
|
55008
|
+
throw new Error('Pro2 host asset package LZ4 block exceeds the firmware buffer limit.');
|
|
55009
|
+
}
|
|
55010
|
+
return fallback;
|
|
55011
|
+
}
|
|
54956
55012
|
const CRC32_TABLE = (() => {
|
|
54957
55013
|
const table = new Uint32Array(256);
|
|
54958
55014
|
for (let index = 0; index < table.length; index += 1) {
|
|
@@ -55039,6 +55095,7 @@ const SAFE_FILE_NAME = /^[A-Za-z0-9_-]+(?:\.bin)?$/;
|
|
|
55039
55095
|
const DEVICE_SETTINGS_SET_MESSAGE_TYPE = 60412;
|
|
55040
55096
|
const FILESYSTEM_FILE_WRITE_MESSAGE_TYPE$2 = 60805;
|
|
55041
55097
|
const FILESYSTEM_DIR_MAKE_MESSAGE_TYPE = 60809;
|
|
55098
|
+
const WALLPAPER_PACKAGE_BLE_CHUNK_SIZE = 1960;
|
|
55042
55099
|
const Log$4 = getLogger(exports.LoggerNames.Method);
|
|
55043
55100
|
function normalizeFileName(fileName, data) {
|
|
55044
55101
|
if (fileName !== undefined && (!fileName || !SAFE_FILE_NAME.test(fileName))) {
|
|
@@ -55110,7 +55167,7 @@ class DeviceUploadWallpaper extends BaseMethod {
|
|
|
55110
55167
|
this.directoryReady = true;
|
|
55111
55168
|
});
|
|
55112
55169
|
}
|
|
55113
|
-
upload(path, data) {
|
|
55170
|
+
upload(path, data, bleChunkSizeLimit) {
|
|
55114
55171
|
return __awaiter(this, void 0, void 0, function* () {
|
|
55115
55172
|
if (this.uploaded)
|
|
55116
55173
|
return;
|
|
@@ -55120,6 +55177,7 @@ class DeviceUploadWallpaper extends BaseMethod {
|
|
|
55120
55177
|
data,
|
|
55121
55178
|
totalSize: data.byteLength,
|
|
55122
55179
|
chunkSize: this.params.chunkSize,
|
|
55180
|
+
bleChunkSizeLimit,
|
|
55123
55181
|
maxChunkRetries: 3,
|
|
55124
55182
|
overwrite: true,
|
|
55125
55183
|
append: false,
|
|
@@ -55147,7 +55205,7 @@ class DeviceUploadWallpaper extends BaseMethod {
|
|
|
55147
55205
|
: encoded.data;
|
|
55148
55206
|
if (useHostAssetPackage)
|
|
55149
55207
|
this.path = WALLPAPER_PACKAGE_PATH;
|
|
55150
|
-
yield this.upload(this.path, data);
|
|
55208
|
+
yield this.upload(this.path, data, useHostAssetPackage ? WALLPAPER_PACKAGE_BLE_CHUNK_SIZE : undefined);
|
|
55151
55209
|
const response = yield this.device.commands.typedCall('DeviceSettingsSet', 'Success', {
|
|
55152
55210
|
settings: { wallpaper_path: this.path },
|
|
55153
55211
|
});
|
|
@@ -66366,18 +66424,19 @@ function connectDeviceForBle(method, device, abortSignal, retryCount = 0) {
|
|
|
66366
66424
|
!device.commands ||
|
|
66367
66425
|
device.commands.disposed;
|
|
66368
66426
|
if (shouldAcquire) {
|
|
66427
|
+
const connectProtocol = resolveBleConnectProtocol(method);
|
|
66369
66428
|
const useAcquireGuards = DataManager.getSettings('env') === 'desktop-web-ble';
|
|
66370
66429
|
if (useAcquireGuards && (abortSignal === null || abortSignal === void 0 ? void 0 : abortSignal.aborted)) {
|
|
66371
66430
|
throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.CallQueueActionCancelled);
|
|
66372
66431
|
}
|
|
66373
66432
|
if (!useAcquireGuards) {
|
|
66374
|
-
yield device.acquire(
|
|
66433
|
+
yield device.acquire(connectProtocol, {
|
|
66375
66434
|
forceProtocolDetection: method.payload.forceProtocolDetection,
|
|
66376
66435
|
});
|
|
66377
66436
|
}
|
|
66378
66437
|
else {
|
|
66379
66438
|
try {
|
|
66380
|
-
yield raceBleAcquire(device.acquire(
|
|
66439
|
+
yield raceBleAcquire(device.acquire(connectProtocol, {
|
|
66381
66440
|
forceProtocolDetection: method.payload.forceProtocolDetection,
|
|
66382
66441
|
}), abortSignal);
|
|
66383
66442
|
}
|
|
@@ -66429,6 +66488,13 @@ function connectDeviceForBle(method, device, abortSignal, retryCount = 0) {
|
|
|
66429
66488
|
}
|
|
66430
66489
|
});
|
|
66431
66490
|
}
|
|
66491
|
+
function resolveBleConnectProtocol(method) {
|
|
66492
|
+
if (method.payload.connectProtocol === 'V1' || method.payload.connectProtocol === 'V2') {
|
|
66493
|
+
return method.payload.connectProtocol;
|
|
66494
|
+
}
|
|
66495
|
+
const supportedProtocols = method.getSupportedProtocols();
|
|
66496
|
+
return supportedProtocols.length === 1 && supportedProtocols[0] === 'V2' ? 'V2' : undefined;
|
|
66497
|
+
}
|
|
66432
66498
|
const ensureConnected = (_context, method, connectId, pollingId, abortSignal) => __awaiter(void 0, void 0, void 0, function* () {
|
|
66433
66499
|
let tryCount = 0;
|
|
66434
66500
|
const MAX_RETRY_COUNT = method.payload && typeof method.payload.retryCount === 'number' ? method.payload.retryCount : 5;
|
|
@@ -66584,7 +66650,7 @@ const cancel = (context, connectId) => {
|
|
|
66584
66650
|
requestQueue.cancelCallbackTasks(connectId);
|
|
66585
66651
|
const requestIds = requestQueue.getRequestTasksId();
|
|
66586
66652
|
Log.debug(`Cancel Api connect requestQueues: length:${requestIds.length} requestIds:${requestIds.join(',')}`);
|
|
66587
|
-
requestQueue.
|
|
66653
|
+
requestQueue.abortAllRequests();
|
|
66588
66654
|
const canceledDevices = [];
|
|
66589
66655
|
const interruptDevice = (device, deviceConnectId) => {
|
|
66590
66656
|
if (!device || canceledDevices.includes(device)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pro2HostAssetPackage.d.ts","sourceRoot":"","sources":["../../src/utils/pro2HostAssetPackage.ts"],"names":[],"mappings":"AAiBA,eAAO,MAAM,mCAAmC,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"pro2HostAssetPackage.d.ts","sourceRoot":"","sources":["../../src/utils/pro2HostAssetPackage.ts"],"names":[],"mappings":"AAiBA,eAAO,MAAM,mCAAmC,UAAU,CAAC;AA0B3D,MAAM,MAAM,yBAAyB,GAAG;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,CAAC;CAClB,CAAC;AAQF,wBAAgB,4BAA4B,CAAC,eAAe,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAMzF;AAuTD,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,yBAAyB,EAAE,GAAG,UAAU,CA4B1F"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@onekeyfe/hd-core",
|
|
3
|
-
"version": "1.2.2-alpha.
|
|
3
|
+
"version": "1.2.2-alpha.7",
|
|
4
4
|
"description": "Core processes and APIs for communicating with OneKey hardware devices.",
|
|
5
5
|
"author": "OneKey",
|
|
6
6
|
"homepage": "https://github.com/OneKeyHQ/hardware-js-sdk#readme",
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"url": "https://github.com/OneKeyHQ/hardware-js-sdk/issues"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@onekeyfe/hd-shared": "1.2.2-alpha.
|
|
29
|
-
"@onekeyfe/hd-transport": "1.2.2-alpha.
|
|
28
|
+
"@onekeyfe/hd-shared": "1.2.2-alpha.7",
|
|
29
|
+
"@onekeyfe/hd-transport": "1.2.2-alpha.7",
|
|
30
30
|
"axios": "1.15.2",
|
|
31
31
|
"bignumber.js": "^9.0.2",
|
|
32
32
|
"buffer": "^6.0.3",
|
|
@@ -46,5 +46,5 @@
|
|
|
46
46
|
"@types/w3c-web-usb": "^1.0.10",
|
|
47
47
|
"@types/web-bluetooth": "^0.0.21"
|
|
48
48
|
},
|
|
49
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "29b87f1c04fea60459d900ef1f61cb9f17eaa4d3"
|
|
50
50
|
}
|
|
@@ -383,6 +383,13 @@ const isProtocolV2InstallResponseTimeout = (error: unknown) => {
|
|
|
383
383
|
);
|
|
384
384
|
};
|
|
385
385
|
|
|
386
|
+
const getProtocolV2ErrorCode = (error: unknown): number | string | undefined => {
|
|
387
|
+
if (!error || typeof error !== 'object') return undefined;
|
|
388
|
+
const { errorCode, code } = error as { errorCode?: unknown; code?: unknown };
|
|
389
|
+
const causeCode = errorCode ?? code;
|
|
390
|
+
return typeof causeCode === 'number' || typeof causeCode === 'string' ? causeCode : undefined;
|
|
391
|
+
};
|
|
392
|
+
|
|
386
393
|
const isProtocolV2TerminalInstallStatusError = (error: unknown) =>
|
|
387
394
|
isBleStaleBondHardwareError(error) ||
|
|
388
395
|
(error instanceof HardwareError &&
|
|
@@ -2114,6 +2121,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2114
2121
|
this.postTipMessage(FirmwareUpdateTipMessage.StartTransferData);
|
|
2115
2122
|
this.protocolV2LastTransferProgress = undefined;
|
|
2116
2123
|
this.protocolV2LastTransferProgressAt = 0;
|
|
2124
|
+
const transferStartedAt = Date.now();
|
|
2117
2125
|
let processedSize = 0;
|
|
2118
2126
|
for (const resource of resourcesToSync) {
|
|
2119
2127
|
// The bootloader keeps its live resource package mounted. FatFs rejects
|
|
@@ -2124,6 +2132,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2124
2132
|
filePath: writePath,
|
|
2125
2133
|
processedSize,
|
|
2126
2134
|
totalSize,
|
|
2135
|
+
transferStartedAt,
|
|
2127
2136
|
});
|
|
2128
2137
|
await this.verifyProtocolV2StagedFile(writePath, resource.source.size);
|
|
2129
2138
|
if (isProtocolV2BootResourcePackagePath(resource.devicePath)) {
|
|
@@ -2139,6 +2148,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2139
2148
|
filePath,
|
|
2140
2149
|
processedSize,
|
|
2141
2150
|
totalSize,
|
|
2151
|
+
transferStartedAt,
|
|
2142
2152
|
});
|
|
2143
2153
|
await this.verifyProtocolV2StagedFile(filePath, item.source.size);
|
|
2144
2154
|
stagedInstallTargets.push({
|
|
@@ -2148,7 +2158,13 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2148
2158
|
}
|
|
2149
2159
|
|
|
2150
2160
|
if (totalSize > 0) {
|
|
2151
|
-
|
|
2161
|
+
const elapsedMs = Math.max(Date.now() - transferStartedAt, 0);
|
|
2162
|
+
this.postProgressMessage(100, 'transferData', {
|
|
2163
|
+
transferredBytes: totalSize,
|
|
2164
|
+
totalBytes: totalSize,
|
|
2165
|
+
rateBytesPerSecond: elapsedMs > 0 ? Math.round((totalSize / elapsedMs) * 1000) : undefined,
|
|
2166
|
+
elapsedMs,
|
|
2167
|
+
});
|
|
2152
2168
|
}
|
|
2153
2169
|
if (stagedInstallTargets.length === 0) {
|
|
2154
2170
|
return;
|
|
@@ -2173,20 +2189,23 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2173
2189
|
filePath,
|
|
2174
2190
|
processedSize,
|
|
2175
2191
|
totalSize,
|
|
2192
|
+
transferStartedAt = Date.now(),
|
|
2176
2193
|
}: {
|
|
2177
2194
|
source: FirmwareByteSource;
|
|
2178
2195
|
filePath: string;
|
|
2179
2196
|
processedSize: number;
|
|
2180
2197
|
totalSize: number;
|
|
2198
|
+
transferStartedAt?: number;
|
|
2181
2199
|
}) {
|
|
2182
2200
|
let lastError: unknown;
|
|
2183
2201
|
for (let attempt = 1; attempt <= PROTOCOL_V2_FILE_TRANSFER_RETRY_COUNT; attempt += 1) {
|
|
2202
|
+
this.throwIfAborted();
|
|
2184
2203
|
try {
|
|
2185
|
-
const transferStartedAt = Date.now();
|
|
2186
2204
|
await writeFirmwareByteSource({
|
|
2187
2205
|
source,
|
|
2188
2206
|
chunkSize: this.getProtocolV2FirmwareChunkSize('write', filePath),
|
|
2189
2207
|
write: async ({ data, sourceOffset, length, first }) => {
|
|
2208
|
+
this.throwIfAborted();
|
|
2190
2209
|
const chunkEnd = sourceOffset + length;
|
|
2191
2210
|
const deviceProgress = getProtocolV2DeviceTransferProgress(
|
|
2192
2211
|
processedSize + sourceOffset,
|
|
@@ -2225,7 +2244,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2225
2244
|
transferredBytes,
|
|
2226
2245
|
totalBytes: totalSize,
|
|
2227
2246
|
rateBytesPerSecond:
|
|
2228
|
-
elapsedMs > 0 ? Math.round((
|
|
2247
|
+
elapsedMs > 0 ? Math.round((transferredBytes / elapsedMs) * 1000) : undefined,
|
|
2229
2248
|
elapsedMs,
|
|
2230
2249
|
});
|
|
2231
2250
|
}
|
|
@@ -2234,18 +2253,22 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2234
2253
|
});
|
|
2235
2254
|
return processedSize + source.size;
|
|
2236
2255
|
} catch (error) {
|
|
2256
|
+
this.throwIfAborted();
|
|
2237
2257
|
if (isBleStaleBondHardwareError(error)) {
|
|
2238
2258
|
throw error;
|
|
2239
2259
|
}
|
|
2240
2260
|
lastError = error;
|
|
2241
2261
|
if (attempt < PROTOCOL_V2_FILE_TRANSFER_RETRY_COUNT) {
|
|
2242
2262
|
await this.recoverProtocolV2FileTransfer();
|
|
2263
|
+
this.throwIfAborted();
|
|
2243
2264
|
}
|
|
2244
2265
|
}
|
|
2245
2266
|
}
|
|
2267
|
+
const causeCode = getProtocolV2ErrorCode(lastError);
|
|
2246
2268
|
throw ERRORS.TypedError(
|
|
2247
2269
|
HardwareErrorCode.EmmcFileWriteFirmwareError,
|
|
2248
|
-
`transfer data error: ${getProtocolV2UnknownErrorText(lastError)}
|
|
2270
|
+
`transfer data error: ${getProtocolV2UnknownErrorText(lastError)}`,
|
|
2271
|
+
causeCode === undefined ? undefined : { causeCode }
|
|
2249
2272
|
);
|
|
2250
2273
|
}
|
|
2251
2274
|
|
|
@@ -2705,7 +2728,9 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
2705
2728
|
if (!hasCurrentInstallEvidence) {
|
|
2706
2729
|
// A successful status poll clears DeviceCommands' cancel action. Keep cancellation
|
|
2707
2730
|
// available while UpdateRequest is still waiting for confirmation on the device.
|
|
2708
|
-
|
|
2731
|
+
// Bootloader does not register the protocol Cancel message. Keep the
|
|
2732
|
+
// operation locally cancellable; interruptionFromUser() disposes the link.
|
|
2733
|
+
this.device.setCancelableAction(() => Promise.resolve());
|
|
2709
2734
|
}
|
|
2710
2735
|
|
|
2711
2736
|
if (
|
|
@@ -3174,7 +3199,9 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
3174
3199
|
this.protocolV2InstallTerminalSuccessObserved = false;
|
|
3175
3200
|
const commands = this.device.getCommands();
|
|
3176
3201
|
await commands.typedCall('DeviceFirmwareUpdateStage', 'Success', { targets });
|
|
3177
|
-
|
|
3202
|
+
// Bootloader does not register the protocol Cancel message. Keep the
|
|
3203
|
+
// operation locally cancellable; interruptionFromUser() disposes the link.
|
|
3204
|
+
this.device.setCancelableAction(() => Promise.resolve());
|
|
3178
3205
|
const interaction = this.device.createProtocolV2UiPhaseMetadata('button', 'start');
|
|
3179
3206
|
this.postMessage(
|
|
3180
3207
|
createUiMessage(UI_REQUEST.REQUEST_BUTTON, {
|
|
@@ -36,6 +36,8 @@ export type ProtocolV2FileWriteOptions = {
|
|
|
36
36
|
chunkSize?: number;
|
|
37
37
|
chunkLen?: number;
|
|
38
38
|
chunkSizeLimit?: number;
|
|
39
|
+
/** BLE-only limit for a caller whose fixed short path has a verified larger frame budget. */
|
|
40
|
+
bleChunkSizeLimit?: number;
|
|
39
41
|
overwrite?: boolean;
|
|
40
42
|
append?: boolean;
|
|
41
43
|
uiPercentage?: number;
|
|
@@ -114,11 +116,15 @@ export function isProtocolV2ResponseTimeout(error: unknown) {
|
|
|
114
116
|
);
|
|
115
117
|
}
|
|
116
118
|
|
|
117
|
-
function getProtocolV2FileChunkLimit() {
|
|
119
|
+
function getProtocolV2FileChunkLimit(bleChunkSizeLimit?: number) {
|
|
118
120
|
const env = DataManager.getSettings('env');
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
121
|
+
if (env && DataManager.isBleConnect(env)) {
|
|
122
|
+
const configuredLimit = Number(bleChunkSizeLimit);
|
|
123
|
+
return Number.isFinite(configuredLimit) && configuredLimit > 0
|
|
124
|
+
? Math.floor(configuredLimit)
|
|
125
|
+
: PROTOCOL_V2_BLE_FILE_CHUNK_SIZE;
|
|
126
|
+
}
|
|
127
|
+
return PROTOCOL_V2_WEBUSB_FILE_CHUNK_SIZE;
|
|
122
128
|
}
|
|
123
129
|
|
|
124
130
|
async function dataToUint8Array(data: ProtocolV2FileWriteData): Promise<Uint8Array> {
|
|
@@ -178,7 +184,7 @@ export async function writeProtocolV2File(options: ProtocolV2FileWriteOptions) {
|
|
|
178
184
|
);
|
|
179
185
|
}
|
|
180
186
|
|
|
181
|
-
const defaultChunkSizeLimit = getProtocolV2FileChunkLimit();
|
|
187
|
+
const defaultChunkSizeLimit = getProtocolV2FileChunkLimit(options.bleChunkSizeLimit);
|
|
182
188
|
const configuredChunkSizeLimit = Number(options.chunkSizeLimit);
|
|
183
189
|
const chunkSizeLimit =
|
|
184
190
|
Number.isFinite(configuredChunkSizeLimit) && configuredChunkSizeLimit > 0
|
|
@@ -49,6 +49,7 @@ const SAFE_FILE_NAME = /^[A-Za-z0-9_-]+(?:\.bin)?$/;
|
|
|
49
49
|
const DEVICE_SETTINGS_SET_MESSAGE_TYPE = 60412;
|
|
50
50
|
const FILESYSTEM_FILE_WRITE_MESSAGE_TYPE = 60805;
|
|
51
51
|
const FILESYSTEM_DIR_MAKE_MESSAGE_TYPE = 60809;
|
|
52
|
+
const WALLPAPER_PACKAGE_BLE_CHUNK_SIZE = 1960;
|
|
52
53
|
const Log = getLogger(LoggerNames.Method);
|
|
53
54
|
|
|
54
55
|
function normalizeFileName(fileName: string | undefined, data: Uint8Array): string {
|
|
@@ -130,7 +131,7 @@ export default class DeviceUploadWallpaper extends BaseMethod<DeviceUploadWallpa
|
|
|
130
131
|
this.directoryReady = true;
|
|
131
132
|
}
|
|
132
133
|
|
|
133
|
-
private async upload(path: string, data: Uint8Array) {
|
|
134
|
+
private async upload(path: string, data: Uint8Array, bleChunkSizeLimit?: number) {
|
|
134
135
|
if (this.uploaded) return;
|
|
135
136
|
|
|
136
137
|
await writeProtocolV2File({
|
|
@@ -139,6 +140,7 @@ export default class DeviceUploadWallpaper extends BaseMethod<DeviceUploadWallpa
|
|
|
139
140
|
data,
|
|
140
141
|
totalSize: data.byteLength,
|
|
141
142
|
chunkSize: this.params.chunkSize,
|
|
143
|
+
bleChunkSizeLimit,
|
|
142
144
|
maxChunkRetries: 3,
|
|
143
145
|
overwrite: true,
|
|
144
146
|
append: false,
|
|
@@ -164,7 +166,11 @@ export default class DeviceUploadWallpaper extends BaseMethod<DeviceUploadWallpa
|
|
|
164
166
|
? buildPro2HostAssetPackage([{ name: WALLPAPER_PACKAGE_ENTRY, data: encoded.data }])
|
|
165
167
|
: encoded.data;
|
|
166
168
|
if (useHostAssetPackage) this.path = WALLPAPER_PACKAGE_PATH;
|
|
167
|
-
await this.upload(
|
|
169
|
+
await this.upload(
|
|
170
|
+
this.path,
|
|
171
|
+
data,
|
|
172
|
+
useHostAssetPackage ? WALLPAPER_PACKAGE_BLE_CHUNK_SIZE : undefined
|
|
173
|
+
);
|
|
168
174
|
const response = await this.device.commands.typedCall('DeviceSettingsSet', 'Success', {
|
|
169
175
|
settings: { wallpaper_path: this.path },
|
|
170
176
|
});
|