@onekeyfe/hd-core 1.2.8-alpha.112 → 1.2.8-alpha.113

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.
@@ -44,6 +44,7 @@ import FirmwareUpdateV3 from '../src/api/FirmwareUpdateV3';
44
44
  import FirmwareUpdateV4, {
45
45
  assertProtocolV2FirmwareTargetsSupported,
46
46
  assertProtocolV2ReconnectIdentity,
47
+ supportsProtocolV2BleFileWriteWindow,
47
48
  } from '../src/api/FirmwareUpdateV4';
48
49
  import GetPassphraseState from '../src/api/GetPassphraseState';
49
50
  import GetOnekeyFeatures from '../src/api/GetOnekeyFeatures';
@@ -8883,6 +8884,244 @@ describe('Protocol V2 firmware update targets', () => {
8883
8884
  expect((method as any).protocolV2SourceUpdateProcess).not.toHaveBeenCalled();
8884
8885
  });
8885
8886
 
8887
+ test.each([
8888
+ ['1.0.3', '1.0.3', true],
8889
+ ['1.0.10', '1.0.3', true],
8890
+ ['1.0.2', '1.0.3', false],
8891
+ ['0.0.0.1', '1.0.3', false],
8892
+ ['1.0.2', undefined, true],
8893
+ ['1.0.1', undefined, false],
8894
+ ] as const)(
8895
+ 'gates the BLE file write window on bootloader %s with minimum %s',
8896
+ (bootloaderVersion, minBootloaderVersion, expected) => {
8897
+ expect(supportsProtocolV2BleFileWriteWindow(bootloaderVersion, minBootloaderVersion)).toBe(
8898
+ expected
8899
+ );
8900
+ }
8901
+ );
8902
+
8903
+ test.each([
8904
+ ['react-native', 'bootloader', true],
8905
+ ['desktop-web-ble', 'bootloader', true],
8906
+ ['lowlevel', 'bootloader', false],
8907
+ ['webusb', 'bootloader', false],
8908
+ ['react-native', 'normal', false],
8909
+ ] as const)(
8910
+ 'enables the BLE file write window for %s in %s mode only with a supported bootloader',
8911
+ (env, mode, expected) => {
8912
+ const getSettingsSpy = jest.spyOn(DataManager, 'getSettings').mockReturnValue(env);
8913
+ const method = new FirmwareUpdateV4({
8914
+ id: 1,
8915
+ payload: {
8916
+ method: 'firmwareUpdateV4',
8917
+ },
8918
+ });
8919
+ (method as any).device = stubDevice({
8920
+ features: { mode, bootloaderMode: mode === 'bootloader', bootloaderVersion: '1.0.3' },
8921
+ });
8922
+
8923
+ try {
8924
+ expect((method as any).shouldUseProtocolV2BleFileWriteWindow('1.0.3')).toBe(expected);
8925
+ expect((method as any).shouldUseProtocolV2BleFileWriteWindow('1.0.4')).toBe(false);
8926
+ } finally {
8927
+ getSettingsSpy.mockRestore();
8928
+ }
8929
+ }
8930
+ );
8931
+
8932
+ describe('windowed BLE file write', () => {
8933
+ const confirm = (request: { file: { offset: number; data: ArrayBuffer } }) => ({
8934
+ type: 'FilesystemFile',
8935
+ message: { processed_byte: request.file.offset + request.file.data.byteLength },
8936
+ });
8937
+ const streamAll = (requests: any[]) =>
8938
+ jest.fn(async (_name: string, _resType: string, first: any, options: any) => {
8939
+ const { next, onResponse } = options.fileWritePipeline;
8940
+ let request = first;
8941
+ let last;
8942
+ while (request) {
8943
+ requests.push(request);
8944
+ last = confirm(request);
8945
+ onResponse(last);
8946
+ request = await next();
8947
+ }
8948
+ return last;
8949
+ });
8950
+ const createMethod = (typedCall: jest.Mock) => {
8951
+ const method = new FirmwareUpdateV4({
8952
+ id: 1,
8953
+ payload: {
8954
+ method: 'firmwareUpdateV4',
8955
+ },
8956
+ });
8957
+ (method as any).device = stubDevice({ getCommands: () => ({ typedCall }) });
8958
+ (method as any).shouldUseProtocolV2BleFileWriteWindow = jest.fn().mockReturnValue(true);
8959
+ (method as any).getProtocolV2FirmwareChunkSize = jest.fn().mockReturnValue(1000);
8960
+ (method as any).recoverProtocolV2FileTransfer = jest.fn().mockResolvedValue(undefined);
8961
+ method.postProgressMessage = jest.fn();
8962
+ return method;
8963
+ };
8964
+ const transfer = async (method: FirmwareUpdateV4) => {
8965
+ const source = await openFirmwareByteSource({ binary: new Uint8Array(2500).buffer });
8966
+ try {
8967
+ const processedSize: number = await (method as any).protocolV2SourceUpdateProcess({
8968
+ source,
8969
+ filePath: 'vol0:/application_p1.bin',
8970
+ processedSize: 500,
8971
+ totalSize: 3000,
8972
+ });
8973
+ return processedSize;
8974
+ } finally {
8975
+ await source?.close();
8976
+ }
8977
+ };
8978
+
8979
+ test('streams the file through one FileWrite call and reports confirmed chunks', async () => {
8980
+ const requests: any[] = [];
8981
+ const typedCall = streamAll(requests);
8982
+ const method = createMethod(typedCall);
8983
+
8984
+ await expect(transfer(method)).resolves.toBe(3000);
8985
+
8986
+ expect(typedCall).toHaveBeenCalledTimes(1);
8987
+ expect(typedCall).toHaveBeenCalledWith(
8988
+ 'FilesystemFileWrite',
8989
+ 'FilesystemFile',
8990
+ expect.anything(),
8991
+ expect.objectContaining({
8992
+ writeWithResponse: false,
8993
+ fileWritePipeline: expect.objectContaining({
8994
+ next: expect.any(Function),
8995
+ onResponse: expect.any(Function),
8996
+ }),
8997
+ })
8998
+ );
8999
+ expect(requests.map(request => request.file.offset)).toEqual([0, 1000, 2000]);
9000
+ expect(requests.map(request => request.file.data.byteLength)).toEqual([1000, 1000, 500]);
9001
+ expect(requests.map(request => request.overwrite)).toEqual([true, false, false]);
9002
+ expect(requests.map(request => request.ui_percentage)).toEqual([50, 84, 99]);
9003
+ expect(
9004
+ requests.every(
9005
+ request =>
9006
+ request.append === false &&
9007
+ request.file.total_size === 2500 &&
9008
+ request.file.path === 'vol0:/application_p1.bin'
9009
+ )
9010
+ ).toBe(true);
9011
+ const transferredBytes = (method.postProgressMessage as jest.Mock).mock.calls.map(
9012
+ ([, , metrics]) => metrics.transferredBytes
9013
+ );
9014
+ expect(transferredBytes).toEqual([1500, 2500, 3000]);
9015
+ });
9016
+
9017
+ test.each([
9018
+ ['react-native', 10_000],
9019
+ ['desktop-web-ble', undefined],
9020
+ ] as const)('uses the serial per-chunk response timeout in %s', async (env, timeoutMs) => {
9021
+ const getSettingsSpy = jest.spyOn(DataManager, 'getSettings').mockReturnValue(env);
9022
+ const typedCall = streamAll([]);
9023
+
9024
+ try {
9025
+ await transfer(createMethod(typedCall));
9026
+ } finally {
9027
+ getSettingsSpy.mockRestore();
9028
+ }
9029
+
9030
+ expect(typedCall.mock.calls[0][3]).toEqual(expect.objectContaining({ timeoutMs }));
9031
+ });
9032
+
9033
+ test('restarts the whole file after a failed windowed write', async () => {
9034
+ const requests: any[] = [];
9035
+ const succeed = streamAll(requests);
9036
+ const typedCall = jest
9037
+ .fn()
9038
+ .mockRejectedValueOnce(new Error('Protocol V2 file write response does not match'))
9039
+ .mockImplementation(succeed);
9040
+ const method = createMethod(typedCall);
9041
+
9042
+ await expect(transfer(method)).resolves.toBe(3000);
9043
+
9044
+ expect((method as any).recoverProtocolV2FileTransfer).toHaveBeenCalledTimes(1);
9045
+ expect(typedCall).toHaveBeenCalledTimes(2);
9046
+ expect(typedCall.mock.calls[1][2]).toEqual(
9047
+ expect.objectContaining({ overwrite: true, file: expect.objectContaining({ offset: 0 }) })
9048
+ );
9049
+ expect(requests.map(request => request.file.offset)).toEqual([0, 1000, 2000]);
9050
+ });
9051
+
9052
+ test('stops sending on cancel and raises it after the transport call returns', async () => {
9053
+ const abortController = new AbortController();
9054
+ const requests: any[] = [];
9055
+ const succeed = streamAll(requests);
9056
+ const typedCall = jest.fn((name: string, resType: string, first: any, options: any) =>
9057
+ succeed(name, resType, first, {
9058
+ ...options,
9059
+ fileWritePipeline: {
9060
+ ...options.fileWritePipeline,
9061
+ onResponse: (response: any) => {
9062
+ options.fileWritePipeline.onResponse(response);
9063
+ abortController.abort();
9064
+ },
9065
+ },
9066
+ })
9067
+ );
9068
+ const method = createMethod(typedCall);
9069
+ method.abortSignal = abortController.signal;
9070
+
9071
+ await expect(transfer(method)).rejects.toMatchObject({
9072
+ errorCode: HardwareErrorCode.CallQueueActionCancelled,
9073
+ });
9074
+ expect(requests.map(request => request.file.offset)).toEqual([0]);
9075
+ expect((method as any).recoverProtocolV2FileTransfer).not.toHaveBeenCalled();
9076
+ });
9077
+
9078
+ test('raises a source read error after the windowed call and retries the file', async () => {
9079
+ const requests: any[] = [];
9080
+ const typedCall = streamAll(requests);
9081
+ const method = createMethod(typedCall);
9082
+ const bytes = new Uint8Array(2500);
9083
+ let failed = false;
9084
+ const source = {
9085
+ size: bytes.length,
9086
+ readAt: jest.fn((offset: number, length: number) => {
9087
+ if (offset === 1000 && !failed) {
9088
+ failed = true;
9089
+ return Promise.reject(new Error('artifact read failed'));
9090
+ }
9091
+ return Promise.resolve(bytes.slice(offset, offset + length).buffer);
9092
+ }),
9093
+ close: jest.fn(),
9094
+ };
9095
+
9096
+ await expect(
9097
+ (method as any).protocolV2SourceUpdateProcess({
9098
+ source,
9099
+ filePath: 'vol0:/application_p1.bin',
9100
+ processedSize: 0,
9101
+ totalSize: 2500,
9102
+ })
9103
+ ).resolves.toBe(2500);
9104
+
9105
+ expect(typedCall).toHaveBeenCalledTimes(2);
9106
+ expect((method as any).recoverProtocolV2FileTransfer).toHaveBeenCalledTimes(1);
9107
+ expect(requests.map(request => request.file.offset)).toEqual([0, 0, 1000, 2000]);
9108
+ });
9109
+
9110
+ test('rejects a windowed write that does not confirm the whole file', async () => {
9111
+ const typedCall = jest.fn((_name: string, _resType: string, first: any) =>
9112
+ Promise.resolve(confirm(first))
9113
+ );
9114
+ const method = createMethod(typedCall);
9115
+
9116
+ await expect(transfer(method)).rejects.toMatchObject({
9117
+ errorCode: HardwareErrorCode.EmmcFileWriteFirmwareError,
9118
+ message: expect.stringContaining('invalid processed_byte 1000 for file size 2500'),
9119
+ });
9120
+ expect(typedCall).toHaveBeenCalledTimes(3);
9121
+ expect((method as any).recoverProtocolV2FileTransfer).toHaveBeenCalledTimes(2);
9122
+ });
9123
+ });
9124
+
8886
9125
  test('uses absolute processed_byte offsets and disables append for firmware file writes', async () => {
8887
9126
  const method = new FirmwareUpdateV4({
8888
9127
  id: 1,
@@ -338,42 +338,6 @@ describe('SearchDevices', () => {
338
338
  }
339
339
  );
340
340
 
341
- test('BLE discovery returns the advertised color letter without a device identity', async () => {
342
- mockIsBleConnect.mockReturnValue(true);
343
-
344
- const descriptor = {
345
- id: 'ble-peripheral-id',
346
- path: 'ble-peripheral-id',
347
- name: 'Neo A1B2',
348
- commType: 'ble',
349
- bleColorCode: 'E',
350
- };
351
- const method = new SearchDevices({
352
- id: 1,
353
- payload: {
354
- method: 'searchDevices',
355
- },
356
- } as any);
357
- method.init();
358
- method.connector = {
359
- enumerate: jest.fn().mockResolvedValue({
360
- descriptors: [descriptor],
361
- }),
362
- } as any;
363
-
364
- await expect(method.run()).resolves.toEqual([
365
- {
366
- ...descriptor,
367
- connectId: 'ble-peripheral-id',
368
- serialNo: null,
369
- uuid: '',
370
- deviceId: null,
371
- deviceType: 'neo',
372
- bleColorCode: 'E',
373
- },
374
- ]);
375
- });
376
-
377
341
  test.each([
378
342
  ['Pro2 A1B2 - Find My', undefined, 'Pro 2 A1B2'],
379
343
  ['Pro2 5E9D - Finde My', undefined, 'Pro 2 5E9D'],
@@ -2,6 +2,7 @@ import { EDeviceType } from '@onekeyfe/hd-shared';
2
2
  import { FirmwareUpdateBaseMethod } from './firmware/FirmwareUpdateBaseMethod';
3
3
  import type { FirmwareUpdateV4Params } from '../types/api/firmwareUpdate';
4
4
  export declare function assertProtocolV2FirmwareTargetsSupported(deviceType: EDeviceType | string | undefined, params: FirmwareUpdateV4Params, hasExplicitTargetSelection?: boolean): void;
5
+ export declare function supportsProtocolV2BleFileWriteWindow(bootloaderVersion: string, minBootloaderVersion?: string | undefined): boolean;
5
6
  export declare const isProtocolV2FirmwareFingerprintValid: (binary: ArrayBuffer | Uint8Array, fingerprint: string | undefined) => boolean;
6
7
  export declare const assertProtocolV2ReconnectIdentity: (expectedSerialNumber?: string, actualSerialNumber?: string, expectedPath?: string, actualPath?: string) => void;
7
8
  export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareUpdateV4Params> {
@@ -99,6 +100,8 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
99
100
  private ensureProtocolV2DeviceAcquired;
100
101
  private isProtocolV2ReconnectIdentityError;
101
102
  private fileWriteChunk;
103
+ private shouldUseProtocolV2BleFileWriteWindow;
104
+ private writeProtocolV2SourceWindowed;
102
105
  private recoverProtocolV2FileTransfer;
103
106
  private acquireProtocolV2BleDevice;
104
107
  private protocolV2StartFirmwareUpdate;
@@ -1 +1 @@
1
- {"version":3,"file":"FirmwareUpdateV4.d.ts","sourceRoot":"","sources":["../../src/api/FirmwareUpdateV4.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"FirmwareUpdateV4.d.ts","sourceRoot":"","sources":["../../src/api/FirmwareUpdateV4.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -383,12 +383,6 @@ type SearchDevice = {
383
383
  deviceType: IDeviceType;
384
384
  name: string;
385
385
  commType: OneKeyDeviceCommType;
386
- /**
387
- * React Native and Electron BLE discovery only. Serial-number color letter ('A'-'Z')
388
- * advertised by Pro2 / Neo, possibly remembered from an earlier advertisement in this
389
- * process. Absent when unknown; the letter's meaning depends on deviceType.
390
- */
391
- bleColorCode?: string;
392
386
  };
393
387
  /** Identity confirmed over USB. The descriptor path is only a transport address. */
394
388
  type UsbDeviceIdentity = {
package/dist/index.js CHANGED
@@ -52631,6 +52631,7 @@ const PROTOCOL_V2_CONNECT_POLL_INTERVAL = 500;
52631
52631
  const PROTOCOL_V2_CONNECT_SINGLE_TIMEOUT = 75 * 1000;
52632
52632
  const PROTOCOL_V2_DEVICE_INFO_READY_TIMEOUT = 30 * 1000;
52633
52633
  const PROTOCOL_V2_FILE_TRANSFER_RETRY_COUNT = 3;
52634
+ const PROTOCOL_V2_BLE_FILE_WRITE_WINDOW_MIN_BOOTLOADER_VERSION = '1.0.2';
52634
52635
  const PROTOCOL_V2_TRANSFER_PROGRESS_HEARTBEAT_MS = 1000;
52635
52636
  const PROTOCOL_V2_INSTALL_STATUS_CONFLICT_CODE = 'FirmwareInstallStatusConflict';
52636
52637
  const PROTOCOL_V2_INSTALL_FAILED_CODE = 'FirmwareInstallFailed';
@@ -52678,6 +52679,11 @@ function assertProtocolV2FirmwareTargetsSupported(deviceType, params, hasExplici
52678
52679
  : `Cannot safely update ${targetList} without a confirmed Pro2 device type`;
52679
52680
  throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.DeviceNotSupportMethod, message);
52680
52681
  }
52682
+ function supportsProtocolV2BleFileWriteWindow(bootloaderVersion, minBootloaderVersion = PROTOCOL_V2_BLE_FILE_WRITE_WINDOW_MIN_BOOTLOADER_VERSION) {
52683
+ return (!!minBootloaderVersion &&
52684
+ !!semver__default["default"].valid(bootloaderVersion) &&
52685
+ semver__default["default"].gte(bootloaderVersion, minBootloaderVersion));
52686
+ }
52681
52687
  const getProtocolV2DeviceTransferProgress = (bytesBeforeChunk, bytesAfterChunk, totalBytes) => {
52682
52688
  if (!Number.isFinite(totalBytes) || totalBytes <= 0) {
52683
52689
  return 0;
@@ -54117,11 +54123,18 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
54117
54123
  }
54118
54124
  if (totalSize > 0) {
54119
54125
  const elapsedMs = Math.max(Date.now() - transferStartedAt, 0);
54126
+ const rateBytesPerSecond = elapsedMs > 0 ? Math.round((totalSize / elapsedMs) * 1000) : undefined;
54120
54127
  this.postProgressMessage(100, 'transferData', {
54121
54128
  transferredBytes: totalSize,
54122
54129
  totalBytes: totalSize,
54123
- rateBytesPerSecond: elapsedMs > 0 ? Math.round((totalSize / elapsedMs) * 1000) : undefined,
54130
+ rateBytesPerSecond,
54131
+ elapsedMs,
54132
+ });
54133
+ Log$6.debug('[FirmwareUpdateV4] Protocol V2 transfer completed', {
54134
+ files: resourcesToSync.length + installSources.length,
54135
+ totalBytes: totalSize,
54124
54136
  elapsedMs,
54137
+ rateBytesPerSecond,
54125
54138
  });
54126
54139
  }
54127
54140
  if (stagedInstallTargets.length === 0) {
@@ -54132,10 +54145,15 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
54132
54145
  target_id: item.targetId,
54133
54146
  path: item.path,
54134
54147
  }));
54148
+ const installStartedAt = Date.now();
54135
54149
  try {
54136
54150
  yield this.protocolV2StartFirmwareUpdate({ targets });
54137
54151
  yield hdShared.wait(PROTOCOL_V2_INSTALL_STATUS_INITIAL_DELAY);
54138
54152
  yield this.waitForProtocolV2FirmwareUpdateComplete(targets, true);
54153
+ Log$6.debug('[FirmwareUpdateV4] Protocol V2 install completed', {
54154
+ targets: targets.length,
54155
+ elapsedMs: Math.max(Date.now() - installStartedAt, 0),
54156
+ });
54139
54157
  }
54140
54158
  finally {
54141
54159
  (_a = this.device) === null || _a === void 0 ? void 0 : _a.clearCancelableAction();
@@ -54144,51 +54162,81 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
54144
54162
  }
54145
54163
  protocolV2SourceUpdateProcess({ source, filePath, processedSize, totalSize, transferStartedAt = Date.now(), }) {
54146
54164
  return __awaiter(this, void 0, void 0, function* () {
54165
+ const reportConfirmedChunk = (chunkEnd) => {
54166
+ const transferredBytes = processedSize + chunkEnd;
54167
+ const now = Date.now();
54168
+ const elapsedMs = Math.max(now - transferStartedAt, 0);
54169
+ const progress = Math.min(Math.ceil((transferredBytes / totalSize) * 100), 99);
54170
+ const shouldPostProgress = transferredBytes >= this.protocolV2LastTransferredBytes &&
54171
+ (progress !== this.protocolV2LastTransferProgress ||
54172
+ now - this.protocolV2LastTransferProgressAt >=
54173
+ PROTOCOL_V2_TRANSFER_PROGRESS_HEARTBEAT_MS ||
54174
+ chunkEnd === source.size);
54175
+ if (shouldPostProgress) {
54176
+ this.protocolV2LastTransferProgress = progress;
54177
+ this.protocolV2LastTransferProgressAt = now;
54178
+ this.protocolV2LastTransferredBytes = transferredBytes;
54179
+ this.postProgressMessage(progress, 'transferData', {
54180
+ transferredBytes,
54181
+ totalBytes: totalSize,
54182
+ rateBytesPerSecond: elapsedMs > 0 ? Math.round((transferredBytes / elapsedMs) * 1000) : undefined,
54183
+ elapsedMs,
54184
+ });
54185
+ }
54186
+ };
54147
54187
  let lastError;
54148
54188
  for (let attempt = 1; attempt <= PROTOCOL_V2_FILE_TRANSFER_RETRY_COUNT; attempt += 1) {
54149
54189
  this.throwIfAborted();
54190
+ const attemptStartedAt = Date.now();
54150
54191
  try {
54151
- yield writeFirmwareByteSource({
54152
- source,
54153
- chunkSize: this.getProtocolV2FirmwareChunkSize('write', filePath),
54154
- write: ({ data, sourceOffset, length, first }) => __awaiter(this, void 0, void 0, function* () {
54155
- this.throwIfAborted();
54156
- const chunkEnd = sourceOffset + length;
54157
- const deviceProgress = getProtocolV2DeviceTransferProgress(processedSize + sourceOffset, processedSize + chunkEnd, totalSize);
54158
- const response = yield this.fileWriteChunk(filePath, source.size, sourceOffset, data, first, deviceProgress);
54159
- const rawProcessedByte = response.message.processed_byte;
54160
- const nextOffset = rawProcessedByte === undefined ? chunkEnd : Number(rawProcessedByte);
54161
- if (!Number.isFinite(nextOffset) || nextOffset !== chunkEnd) {
54162
- throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.EmmcFileWriteFirmwareError, `invalid processed_byte ${rawProcessedByte} for offset ${sourceOffset}`);
54163
- }
54164
- const transferredBytes = processedSize + chunkEnd;
54165
- const now = Date.now();
54166
- const elapsedMs = Math.max(now - transferStartedAt, 0);
54167
- const progress = Math.min(Math.ceil((transferredBytes / totalSize) * 100), 99);
54168
- const shouldPostProgress = transferredBytes >= this.protocolV2LastTransferredBytes &&
54169
- (progress !== this.protocolV2LastTransferProgress ||
54170
- now - this.protocolV2LastTransferProgressAt >=
54171
- PROTOCOL_V2_TRANSFER_PROGRESS_HEARTBEAT_MS ||
54172
- chunkEnd === source.size);
54173
- if (shouldPostProgress) {
54174
- this.protocolV2LastTransferProgress = progress;
54175
- this.protocolV2LastTransferProgressAt = now;
54176
- this.protocolV2LastTransferredBytes = transferredBytes;
54177
- this.postProgressMessage(progress, 'transferData', {
54178
- transferredBytes,
54179
- totalBytes: totalSize,
54180
- rateBytesPerSecond: elapsedMs > 0 ? Math.round((transferredBytes / elapsedMs) * 1000) : undefined,
54181
- elapsedMs,
54182
- });
54183
- }
54184
- return length;
54185
- }),
54192
+ const chunkSize = this.getProtocolV2FirmwareChunkSize('write', filePath);
54193
+ const windowed = this.shouldUseProtocolV2BleFileWriteWindow();
54194
+ if (windowed) {
54195
+ yield this.writeProtocolV2SourceWindowed({
54196
+ source,
54197
+ filePath,
54198
+ chunkSize,
54199
+ processedSize,
54200
+ totalSize,
54201
+ onChunkConfirmed: reportConfirmedChunk,
54202
+ });
54203
+ }
54204
+ else {
54205
+ yield writeFirmwareByteSource({
54206
+ source,
54207
+ chunkSize,
54208
+ write: ({ data, sourceOffset, length, first }) => __awaiter(this, void 0, void 0, function* () {
54209
+ this.throwIfAborted();
54210
+ const chunkEnd = sourceOffset + length;
54211
+ const deviceProgress = getProtocolV2DeviceTransferProgress(processedSize + sourceOffset, processedSize + chunkEnd, totalSize);
54212
+ const response = yield this.fileWriteChunk(filePath, source.size, sourceOffset, data, first, deviceProgress);
54213
+ const rawProcessedByte = response.message.processed_byte;
54214
+ const nextOffset = rawProcessedByte === undefined ? chunkEnd : Number(rawProcessedByte);
54215
+ if (!Number.isFinite(nextOffset) || nextOffset !== chunkEnd) {
54216
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.EmmcFileWriteFirmwareError, `invalid processed_byte ${rawProcessedByte} for offset ${sourceOffset}`);
54217
+ }
54218
+ reportConfirmedChunk(chunkEnd);
54219
+ return length;
54220
+ }),
54221
+ });
54222
+ }
54223
+ Log$6.debug('[FirmwareUpdateV4] Protocol V2 file transferred', {
54224
+ path: filePath,
54225
+ bytes: source.size,
54226
+ elapsedMs: Math.max(Date.now() - attemptStartedAt, 0),
54227
+ attempt,
54228
+ fileWriteWindow: windowed ? hdTransport.PROTOCOL_V2_FILE_WRITE_PIPELINE_WINDOW : 1,
54186
54229
  });
54187
54230
  return processedSize + source.size;
54188
54231
  }
54189
54232
  catch (error) {
54190
54233
  this.throwIfAborted();
54191
54234
  lastError = error;
54235
+ Log$6.debug('[FirmwareUpdateV4] Protocol V2 file transfer attempt failed', {
54236
+ path: filePath,
54237
+ attempt,
54238
+ error: getProtocolV2UnknownErrorText(error),
54239
+ });
54192
54240
  if (attempt < PROTOCOL_V2_FILE_TRANSFER_RETRY_COUNT) {
54193
54241
  yield this.recoverProtocolV2FileTransfer();
54194
54242
  this.throwIfAborted();
@@ -54871,6 +54919,76 @@ class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod {
54871
54919
  return writeRes;
54872
54920
  });
54873
54921
  }
54922
+ shouldUseProtocolV2BleFileWriteWindow(minBootloaderVersion = PROTOCOL_V2_BLE_FILE_WRITE_WINDOW_MIN_BOOTLOADER_VERSION) {
54923
+ var _a, _b;
54924
+ const env = DataManager.getSettings('env');
54925
+ if ((env !== 'react-native' && env !== 'desktop-web-ble') ||
54926
+ !this.isProtocolV2BootloaderMode()) {
54927
+ return false;
54928
+ }
54929
+ const bootloaderVersion = getDeviceBootloaderVersion(this.device.features).join('.');
54930
+ const enabled = supportsProtocolV2BleFileWriteWindow(bootloaderVersion, minBootloaderVersion);
54931
+ Log$6.debug('[FirmwareUpdateV4] BLE FileWrite window', {
54932
+ enabled,
54933
+ bootloaderVersion,
54934
+ bootloaderBuildId: (_b = (_a = this.device.features) === null || _a === void 0 ? void 0 : _a.verify) === null || _b === void 0 ? void 0 : _b.bootloaderBuildId,
54935
+ });
54936
+ return enabled;
54937
+ }
54938
+ writeProtocolV2SourceWindowed({ source, filePath, chunkSize, processedSize, totalSize, onChunkConfirmed, }) {
54939
+ return __awaiter(this, void 0, void 0, function* () {
54940
+ let sendOffset = 0;
54941
+ let sourceError;
54942
+ const readRequest = () => __awaiter(this, void 0, void 0, function* () {
54943
+ const offset = sendOffset;
54944
+ const length = Math.min(chunkSize, source.size - offset);
54945
+ const data = yield source.readAt(offset, length);
54946
+ sendOffset += length;
54947
+ return {
54948
+ file: { path: filePath, offset, total_size: source.size, data },
54949
+ overwrite: offset === 0,
54950
+ append: false,
54951
+ ui_percentage: getProtocolV2DeviceTransferProgress(processedSize + offset, processedSize + sendOffset, totalSize),
54952
+ };
54953
+ });
54954
+ const nextRequest = () => __awaiter(this, void 0, void 0, function* () {
54955
+ var _a;
54956
+ if (((_a = this.abortSignal) === null || _a === void 0 ? void 0 : _a.aborted) || sendOffset >= source.size)
54957
+ return undefined;
54958
+ try {
54959
+ return yield readRequest();
54960
+ }
54961
+ catch (error) {
54962
+ sourceError = error;
54963
+ return undefined;
54964
+ }
54965
+ });
54966
+ this.throwIfAborted();
54967
+ if (source.size === 0)
54968
+ return;
54969
+ const firstRequest = yield readRequest();
54970
+ const env = DataManager.getSettings('env');
54971
+ const response = yield this.device
54972
+ .getCommands()
54973
+ .typedCall('FilesystemFileWrite', 'FilesystemFile', firstRequest, {
54974
+ timeoutMs: env === 'react-native' ? PROTOCOL_V2_FILE_WRITE_RESPONSE_TIMEOUT : undefined,
54975
+ writeWithResponse: false,
54976
+ fileWritePipeline: {
54977
+ next: nextRequest,
54978
+ onResponse: confirmed => {
54979
+ onChunkConfirmed(Number(confirmed.message.processed_byte));
54980
+ },
54981
+ },
54982
+ });
54983
+ this.throwIfAborted();
54984
+ if (sourceError)
54985
+ throw sourceError;
54986
+ const rawProcessedByte = response.message.processed_byte;
54987
+ if (Number(rawProcessedByte) !== source.size) {
54988
+ throw hdShared.ERRORS.TypedError(hdShared.HardwareErrorCode.EmmcFileWriteFirmwareError, `invalid processed_byte ${rawProcessedByte} for file size ${source.size}`);
54989
+ }
54990
+ });
54991
+ }
54874
54992
  recoverProtocolV2FileTransfer() {
54875
54993
  return __awaiter(this, void 0, void 0, function* () {
54876
54994
  const env = DataManager.getSettings('env');
@@ -46,7 +46,6 @@ export type SearchDevice = {
46
46
  deviceType: IDeviceType;
47
47
  name: string;
48
48
  commType: OneKeyDeviceCommType;
49
- bleColorCode?: string;
50
49
  };
51
50
  export type UsbDeviceIdentity = {
52
51
  path: string;
@@ -1 +1 @@
1
- {"version":3,"file":"device.d.ts","sourceRoot":"","sources":["../../src/types/device.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"device.d.ts","sourceRoot":"","sources":["../../src/types/device.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onekeyfe/hd-core",
3
- "version": "1.2.8-alpha.112",
3
+ "version": "1.2.8-alpha.113",
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.8-alpha.112",
29
- "@onekeyfe/hd-transport": "1.2.8-alpha.112",
28
+ "@onekeyfe/hd-shared": "1.2.8-alpha.113",
29
+ "@onekeyfe/hd-transport": "1.2.8-alpha.113",
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": "d6f1b4cbc6a1c60bb158d70bae93f81c3b07ed1e"
49
+ "gitHead": "c56caf8fdd87e3a00bdc90aca044e75693704ae3"
50
50
  }
@@ -1,11 +1,13 @@
1
1
  import { EDeviceType, ERRORS, HardwareError, HardwareErrorCode, wait } from '@onekeyfe/hd-shared';
2
2
  import JSZip from 'jszip';
3
+ import semver from 'semver';
3
4
  import {
4
5
  DeviceRebootType,
5
6
  DeviceSessionPinType,
6
7
  PROTOCOL_V2_BLE_FILE_CHUNK_SIZE,
7
8
  PROTOCOL_V2_BLE_FILE_READ_CHUNK_SIZE,
8
9
  PROTOCOL_V2_BLE_FIRMWARE_FILE_CHUNK_SIZE,
10
+ PROTOCOL_V2_FILE_WRITE_PIPELINE_WINDOW,
9
11
  PROTOCOL_V2_WEBUSB_FILE_CHUNK_SIZE,
10
12
  } from '@onekeyfe/hd-transport';
11
13
  import { sha256 } from '@noble/hashes/sha256';
@@ -101,6 +103,14 @@ const PROTOCOL_V2_CONNECT_POLL_INTERVAL = 500;
101
103
  const PROTOCOL_V2_CONNECT_SINGLE_TIMEOUT = 75 * 1000;
102
104
  const PROTOCOL_V2_DEVICE_INFO_READY_TIMEOUT = 30 * 1000;
103
105
  const PROTOCOL_V2_FILE_TRANSFER_RETRY_COUNT = 3;
106
+ // Bootloaders with the 2048-byte BLE UART FIFO have no room beside one waiting FileWrite
107
+ // frame, so a second in-flight write can overflow it and lose a chunk. Firmware has not yet
108
+ // confirmed which bootloader version ships the 4096-byte FIFO, nor that the BLE coprocessor
109
+ // queues absorb two back-to-back frames.
110
+ // TEST ONLY: 1.0.2 also matches released bootloaders with the 2048-byte FIFO, so this build
111
+ // must only update test devices flashed with the 4096-byte FIFO bootloader. Replace it with
112
+ // the first released version that ships the 4096-byte FIFO before any release.
113
+ const PROTOCOL_V2_BLE_FILE_WRITE_WINDOW_MIN_BOOTLOADER_VERSION: string | undefined = '1.0.2';
104
114
  const PROTOCOL_V2_TRANSFER_PROGRESS_HEARTBEAT_MS = 1000;
105
115
  const PROTOCOL_V2_INSTALL_STATUS_CONFLICT_CODE = 'FirmwareInstallStatusConflict';
106
116
  const PROTOCOL_V2_INSTALL_FAILED_CODE = 'FirmwareInstallFailed';
@@ -170,6 +180,18 @@ export function assertProtocolV2FirmwareTargetsSupported(
170
180
  throw ERRORS.TypedError(HardwareErrorCode.DeviceNotSupportMethod, message);
171
181
  }
172
182
 
183
+ /** Whether the running bootloader accepts a second in-flight BLE FilesystemFileWrite. */
184
+ export function supportsProtocolV2BleFileWriteWindow(
185
+ bootloaderVersion: string,
186
+ minBootloaderVersion = PROTOCOL_V2_BLE_FILE_WRITE_WINDOW_MIN_BOOTLOADER_VERSION
187
+ ) {
188
+ return (
189
+ !!minBootloaderVersion &&
190
+ !!semver.valid(bootloaderVersion) &&
191
+ semver.gte(bootloaderVersion, minBootloaderVersion)
192
+ );
193
+ }
194
+
173
195
  const getProtocolV2DeviceTransferProgress = (
174
196
  bytesBeforeChunk: number,
175
197
  bytesAfterChunk: number,
@@ -2163,12 +2185,20 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
2163
2185
 
2164
2186
  if (totalSize > 0) {
2165
2187
  const elapsedMs = Math.max(Date.now() - transferStartedAt, 0);
2188
+ const rateBytesPerSecond =
2189
+ elapsedMs > 0 ? Math.round((totalSize / elapsedMs) * 1000) : undefined;
2166
2190
  this.postProgressMessage(100, 'transferData', {
2167
2191
  transferredBytes: totalSize,
2168
2192
  totalBytes: totalSize,
2169
- rateBytesPerSecond: elapsedMs > 0 ? Math.round((totalSize / elapsedMs) * 1000) : undefined,
2193
+ rateBytesPerSecond,
2170
2194
  elapsedMs,
2171
2195
  });
2196
+ Log.debug('[FirmwareUpdateV4] Protocol V2 transfer completed', {
2197
+ files: resourcesToSync.length + installSources.length,
2198
+ totalBytes: totalSize,
2199
+ elapsedMs,
2200
+ rateBytesPerSecond,
2201
+ });
2172
2202
  }
2173
2203
  if (stagedInstallTargets.length === 0) {
2174
2204
  return;
@@ -2179,10 +2209,16 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
2179
2209
  target_id: item.targetId,
2180
2210
  path: item.path,
2181
2211
  }));
2212
+ // Includes the wait for on-device confirmation.
2213
+ const installStartedAt = Date.now();
2182
2214
  try {
2183
2215
  await this.protocolV2StartFirmwareUpdate({ targets });
2184
2216
  await wait(PROTOCOL_V2_INSTALL_STATUS_INITIAL_DELAY);
2185
2217
  await this.waitForProtocolV2FirmwareUpdateComplete(targets, true);
2218
+ Log.debug('[FirmwareUpdateV4] Protocol V2 install completed', {
2219
+ targets: targets.length,
2220
+ elapsedMs: Math.max(Date.now() - installStartedAt, 0),
2221
+ });
2186
2222
  } finally {
2187
2223
  this.device?.clearCancelableAction();
2188
2224
  }
@@ -2201,66 +2237,96 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
2201
2237
  totalSize: number;
2202
2238
  transferStartedAt?: number;
2203
2239
  }) {
2240
+ const reportConfirmedChunk = (chunkEnd: number) => {
2241
+ const transferredBytes = processedSize + chunkEnd;
2242
+ const now = Date.now();
2243
+ const elapsedMs = Math.max(now - transferStartedAt, 0);
2244
+ const progress = Math.min(Math.ceil((transferredBytes / totalSize) * 100), 99);
2245
+ const shouldPostProgress =
2246
+ transferredBytes >= this.protocolV2LastTransferredBytes &&
2247
+ (progress !== this.protocolV2LastTransferProgress ||
2248
+ now - this.protocolV2LastTransferProgressAt >=
2249
+ PROTOCOL_V2_TRANSFER_PROGRESS_HEARTBEAT_MS ||
2250
+ chunkEnd === source.size);
2251
+ if (shouldPostProgress) {
2252
+ this.protocolV2LastTransferProgress = progress;
2253
+ this.protocolV2LastTransferProgressAt = now;
2254
+ this.protocolV2LastTransferredBytes = transferredBytes;
2255
+ this.postProgressMessage(progress, 'transferData', {
2256
+ transferredBytes,
2257
+ totalBytes: totalSize,
2258
+ rateBytesPerSecond:
2259
+ elapsedMs > 0 ? Math.round((transferredBytes / elapsedMs) * 1000) : undefined,
2260
+ elapsedMs,
2261
+ });
2262
+ }
2263
+ };
2204
2264
  let lastError: unknown;
2205
2265
  for (let attempt = 1; attempt <= PROTOCOL_V2_FILE_TRANSFER_RETRY_COUNT; attempt += 1) {
2206
2266
  this.throwIfAborted();
2267
+ const attemptStartedAt = Date.now();
2207
2268
  try {
2208
- await writeFirmwareByteSource({
2209
- source,
2210
- chunkSize: this.getProtocolV2FirmwareChunkSize('write', filePath),
2211
- write: async ({ data, sourceOffset, length, first }) => {
2212
- this.throwIfAborted();
2213
- const chunkEnd = sourceOffset + length;
2214
- const deviceProgress = getProtocolV2DeviceTransferProgress(
2215
- processedSize + sourceOffset,
2216
- processedSize + chunkEnd,
2217
- totalSize
2218
- );
2219
- const response = await this.fileWriteChunk(
2220
- filePath,
2221
- source.size,
2222
- sourceOffset,
2223
- data,
2224
- first,
2225
- deviceProgress
2226
- );
2227
- const rawProcessedByte = response.message.processed_byte;
2228
- const nextOffset = rawProcessedByte === undefined ? chunkEnd : Number(rawProcessedByte);
2229
- if (!Number.isFinite(nextOffset) || nextOffset !== chunkEnd) {
2230
- throw ERRORS.TypedError(
2231
- HardwareErrorCode.EmmcFileWriteFirmwareError,
2232
- `invalid processed_byte ${rawProcessedByte} for offset ${sourceOffset}`
2269
+ const chunkSize = this.getProtocolV2FirmwareChunkSize('write', filePath);
2270
+ const windowed = this.shouldUseProtocolV2BleFileWriteWindow();
2271
+ if (windowed) {
2272
+ await this.writeProtocolV2SourceWindowed({
2273
+ source,
2274
+ filePath,
2275
+ chunkSize,
2276
+ processedSize,
2277
+ totalSize,
2278
+ onChunkConfirmed: reportConfirmedChunk,
2279
+ });
2280
+ } else {
2281
+ await writeFirmwareByteSource({
2282
+ source,
2283
+ chunkSize,
2284
+ write: async ({ data, sourceOffset, length, first }) => {
2285
+ this.throwIfAborted();
2286
+ const chunkEnd = sourceOffset + length;
2287
+ const deviceProgress = getProtocolV2DeviceTransferProgress(
2288
+ processedSize + sourceOffset,
2289
+ processedSize + chunkEnd,
2290
+ totalSize
2233
2291
  );
2234
- }
2235
- const transferredBytes = processedSize + chunkEnd;
2236
- const now = Date.now();
2237
- const elapsedMs = Math.max(now - transferStartedAt, 0);
2238
- const progress = Math.min(Math.ceil((transferredBytes / totalSize) * 100), 99);
2239
- const shouldPostProgress =
2240
- transferredBytes >= this.protocolV2LastTransferredBytes &&
2241
- (progress !== this.protocolV2LastTransferProgress ||
2242
- now - this.protocolV2LastTransferProgressAt >=
2243
- PROTOCOL_V2_TRANSFER_PROGRESS_HEARTBEAT_MS ||
2244
- chunkEnd === source.size);
2245
- if (shouldPostProgress) {
2246
- this.protocolV2LastTransferProgress = progress;
2247
- this.protocolV2LastTransferProgressAt = now;
2248
- this.protocolV2LastTransferredBytes = transferredBytes;
2249
- this.postProgressMessage(progress, 'transferData', {
2250
- transferredBytes,
2251
- totalBytes: totalSize,
2252
- rateBytesPerSecond:
2253
- elapsedMs > 0 ? Math.round((transferredBytes / elapsedMs) * 1000) : undefined,
2254
- elapsedMs,
2255
- });
2256
- }
2257
- return length;
2258
- },
2292
+ const response = await this.fileWriteChunk(
2293
+ filePath,
2294
+ source.size,
2295
+ sourceOffset,
2296
+ data,
2297
+ first,
2298
+ deviceProgress
2299
+ );
2300
+ const rawProcessedByte = response.message.processed_byte;
2301
+ const nextOffset =
2302
+ rawProcessedByte === undefined ? chunkEnd : Number(rawProcessedByte);
2303
+ if (!Number.isFinite(nextOffset) || nextOffset !== chunkEnd) {
2304
+ throw ERRORS.TypedError(
2305
+ HardwareErrorCode.EmmcFileWriteFirmwareError,
2306
+ `invalid processed_byte ${rawProcessedByte} for offset ${sourceOffset}`
2307
+ );
2308
+ }
2309
+ reportConfirmedChunk(chunkEnd);
2310
+ return length;
2311
+ },
2312
+ });
2313
+ }
2314
+ Log.debug('[FirmwareUpdateV4] Protocol V2 file transferred', {
2315
+ path: filePath,
2316
+ bytes: source.size,
2317
+ elapsedMs: Math.max(Date.now() - attemptStartedAt, 0),
2318
+ attempt,
2319
+ fileWriteWindow: windowed ? PROTOCOL_V2_FILE_WRITE_PIPELINE_WINDOW : 1,
2259
2320
  });
2260
2321
  return processedSize + source.size;
2261
2322
  } catch (error) {
2262
2323
  this.throwIfAborted();
2263
2324
  lastError = error;
2325
+ Log.debug('[FirmwareUpdateV4] Protocol V2 file transfer attempt failed', {
2326
+ path: filePath,
2327
+ attempt,
2328
+ error: getProtocolV2UnknownErrorText(error),
2329
+ });
2264
2330
  if (attempt < PROTOCOL_V2_FILE_TRANSFER_RETRY_COUNT) {
2265
2331
  await this.recoverProtocolV2FileTransfer();
2266
2332
  this.throwIfAborted();
@@ -3192,6 +3258,105 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
3192
3258
  return writeRes;
3193
3259
  }
3194
3260
 
3261
+ private shouldUseProtocolV2BleFileWriteWindow(
3262
+ minBootloaderVersion = PROTOCOL_V2_BLE_FILE_WRITE_WINDOW_MIN_BOOTLOADER_VERSION
3263
+ ) {
3264
+ const env = DataManager.getSettings('env');
3265
+ // These adapters queue frames that arrive while no read is pending. LowLevel plugins are not
3266
+ // required to keep notifications between receive() calls, so they stay serial.
3267
+ if (
3268
+ (env !== 'react-native' && env !== 'desktop-web-ble') ||
3269
+ !this.isProtocolV2BootloaderMode()
3270
+ ) {
3271
+ return false;
3272
+ }
3273
+ // The transfer runs in the device's current bootloader, not the one being installed.
3274
+ const bootloaderVersion = getDeviceBootloaderVersion(this.device.features).join('.');
3275
+ const enabled = supportsProtocolV2BleFileWriteWindow(bootloaderVersion, minBootloaderVersion);
3276
+ Log.debug('[FirmwareUpdateV4] BLE FileWrite window', {
3277
+ enabled,
3278
+ bootloaderVersion,
3279
+ bootloaderBuildId: this.device.features?.verify?.bootloaderBuildId,
3280
+ });
3281
+ return enabled;
3282
+ }
3283
+
3284
+ /**
3285
+ * Streams one staged file as a single ordered FilesystemFileWrite pipeline. Every chunk is
3286
+ * still confirmed by the device; a failure restarts the whole file like the serial path.
3287
+ * Cancellation and source errors only stop the pipeline and are raised after the transport
3288
+ * call returns: an error thrown inside it would invalidate the BLE link.
3289
+ */
3290
+ private async writeProtocolV2SourceWindowed({
3291
+ source,
3292
+ filePath,
3293
+ chunkSize,
3294
+ processedSize,
3295
+ totalSize,
3296
+ onChunkConfirmed,
3297
+ }: {
3298
+ source: FirmwareByteSource;
3299
+ filePath: string;
3300
+ chunkSize: number;
3301
+ processedSize: number;
3302
+ totalSize: number;
3303
+ onChunkConfirmed: (chunkEnd: number) => void;
3304
+ }) {
3305
+ let sendOffset = 0;
3306
+ let sourceError: Error | undefined;
3307
+ const readRequest = async () => {
3308
+ const offset = sendOffset;
3309
+ const length = Math.min(chunkSize, source.size - offset);
3310
+ const data = await source.readAt(offset, length);
3311
+ sendOffset += length;
3312
+ return {
3313
+ file: { path: filePath, offset, total_size: source.size, data },
3314
+ overwrite: offset === 0,
3315
+ append: false,
3316
+ ui_percentage: getProtocolV2DeviceTransferProgress(
3317
+ processedSize + offset,
3318
+ processedSize + sendOffset,
3319
+ totalSize
3320
+ ),
3321
+ };
3322
+ };
3323
+ const nextRequest = async () => {
3324
+ if (this.abortSignal?.aborted || sendOffset >= source.size) return undefined;
3325
+ try {
3326
+ return await readRequest();
3327
+ } catch (error) {
3328
+ sourceError = error;
3329
+ return undefined;
3330
+ }
3331
+ };
3332
+ this.throwIfAborted();
3333
+ if (source.size === 0) return;
3334
+ const firstRequest = await readRequest();
3335
+
3336
+ const env = DataManager.getSettings('env');
3337
+ const response = await this.device
3338
+ .getCommands()
3339
+ .typedCall('FilesystemFileWrite', 'FilesystemFile', firstRequest, {
3340
+ timeoutMs: env === 'react-native' ? PROTOCOL_V2_FILE_WRITE_RESPONSE_TIMEOUT : undefined,
3341
+ writeWithResponse: false,
3342
+ fileWritePipeline: {
3343
+ next: nextRequest,
3344
+ onResponse: confirmed => {
3345
+ onChunkConfirmed(Number(confirmed.message.processed_byte));
3346
+ },
3347
+ },
3348
+ });
3349
+ this.throwIfAborted();
3350
+ if (sourceError) throw sourceError;
3351
+ const rawProcessedByte = response.message.processed_byte;
3352
+ if (Number(rawProcessedByte) !== source.size) {
3353
+ throw ERRORS.TypedError(
3354
+ HardwareErrorCode.EmmcFileWriteFirmwareError,
3355
+ `invalid processed_byte ${rawProcessedByte} for file size ${source.size}`
3356
+ );
3357
+ }
3358
+ }
3359
+
3195
3360
  private async recoverProtocolV2FileTransfer() {
3196
3361
  const env = DataManager.getSettings('env');
3197
3362
  if (DataManager.isBleConnect(env)) {
@@ -83,12 +83,6 @@ export type SearchDevice = {
83
83
  deviceType: IDeviceType;
84
84
  name: string;
85
85
  commType: OneKeyDeviceCommType;
86
- /**
87
- * React Native and Electron BLE discovery only. Serial-number color letter ('A'-'Z')
88
- * advertised by Pro2 / Neo, possibly remembered from an earlier advertisement in this
89
- * process. Absent when unknown; the letter's meaning depends on deviceType.
90
- */
91
- bleColorCode?: string;
92
86
  };
93
87
 
94
88
  /** Identity confirmed over USB. The descriptor path is only a transport address. */