@onekeyfe/hd-core 1.2.0-alpha.4 → 1.2.0-alpha.40
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__/AllNetworkGetAddressBase.tracing.test.ts +155 -0
- package/__tests__/DeviceCommands.test.ts +517 -0
- package/__tests__/DeviceEventRegistration.test.ts +49 -0
- package/__tests__/chain-params-onekey-compatibility.test.ts +229 -0
- package/__tests__/check-all-firmware-release-protocol-v2.test.ts +282 -0
- package/__tests__/connectSettings.test.ts +19 -0
- package/__tests__/core-dispose.test.ts +34 -0
- package/__tests__/core-error-output.test.ts +39 -0
- package/__tests__/device-features-state.test.ts +78 -0
- package/__tests__/device-identity.test.ts +52 -0
- package/__tests__/device-lifecycle-events.test.ts +249 -0
- package/__tests__/device-pool-state.test.ts +144 -0
- package/__tests__/device-settings.test.ts +416 -0
- package/__tests__/device-state-contract.test.ts +27 -0
- package/__tests__/device-state-events.test.ts +286 -0
- package/__tests__/device-state-mapper.test.ts +261 -0
- package/__tests__/device-state-projector.test.ts +94 -0
- package/__tests__/device-state-store.test.ts +82 -0
- package/__tests__/device-utils.test.ts +107 -0
- package/__tests__/device-wallet-session-store.test.ts +478 -0
- package/__tests__/deviceFeaturesUtils.test.ts +39 -0
- package/__tests__/deviceSettings.test.ts +103 -0
- package/__tests__/deviceUploadNft.test.ts +187 -0
- package/__tests__/evmLedgerLegacySafety.test.ts +12 -6
- package/__tests__/evmSignTransaction.test.ts +69 -0
- package/__tests__/evmSignTypedData.test.ts +80 -0
- package/__tests__/filesystemValidation.test.ts +53 -0
- package/__tests__/firmware-update/firmware-update-v2-download-before-boot.test.ts +402 -0
- package/__tests__/get-device-state.test.ts +578 -0
- package/__tests__/homescreen.test.ts +64 -0
- package/__tests__/kaspa-public-types.type-test.ts +16 -0
- package/__tests__/kaspa-use-tweak-pro2.test.ts +20 -0
- package/__tests__/kaspaSignTransaction.test.ts +601 -0
- package/__tests__/known-device-public-types.type-test.ts +3 -0
- package/__tests__/logBlockEvent.test.ts +128 -1
- package/__tests__/method-protocol-support.test.ts +113 -0
- package/__tests__/networkUtils.test.ts +406 -0
- package/__tests__/open-wallet-session-error-response.test.ts +43 -0
- package/__tests__/open-wallet-session.test.ts +1609 -0
- package/__tests__/pro2Nft.test.ts +108 -0
- package/__tests__/pro2Wallpaper.test.ts +39 -0
- package/__tests__/protocol-v2-bootloader-mode.test.ts +37 -0
- package/__tests__/protocol-v2-firmware-targets.test.ts +37 -0
- package/__tests__/protocol-v2-ping.test.ts +28 -0
- package/__tests__/protocol-v2-ui-lifecycle.test.ts +56 -0
- package/__tests__/protocol-v2-unlock-policy.test.ts +96 -0
- package/__tests__/protocol-v2.test.ts +5748 -2387
- package/__tests__/protocolV2FileWrite.test.ts +92 -0
- package/__tests__/protocolV2UiInteraction.test.ts +266 -0
- package/__tests__/public-device-state-api.test.ts +275 -0
- package/__tests__/public-pro2-api-boundary.test.ts +107 -0
- package/__tests__/refresh-device-state.test.ts +101 -0
- package/__tests__/request-context-logging.test.ts +16 -0
- package/__tests__/search-devices.test.ts +136 -0
- package/__tests__/tron-sign-message-init.test.ts +74 -0
- package/__tests__/uiProgressThrottle.test.ts +74 -0
- package/dist/api/BaseMethod.d.ts +16 -1
- package/dist/api/BaseMethod.d.ts.map +1 -1
- package/dist/api/CheckAllFirmwareRelease.d.ts +24 -1
- package/dist/api/CheckAllFirmwareRelease.d.ts.map +1 -1
- package/dist/api/CheckBootloaderRelease.d.ts.map +1 -1
- package/dist/api/CheckFirmwareRelease.d.ts.map +1 -1
- package/dist/api/CipherKeyValue.d.ts +1 -0
- package/dist/api/CipherKeyValue.d.ts.map +1 -1
- package/dist/api/ClearSessionCache.d.ts +9 -0
- package/dist/api/ClearSessionCache.d.ts.map +1 -0
- package/dist/api/DirList.d.ts +1 -0
- package/dist/api/DirList.d.ts.map +1 -1
- package/dist/api/DirMake.d.ts +1 -0
- package/dist/api/DirMake.d.ts.map +1 -1
- package/dist/api/DirRemove.d.ts +1 -0
- package/dist/api/DirRemove.d.ts.map +1 -1
- package/dist/api/FileDelete.d.ts +1 -0
- package/dist/api/FileDelete.d.ts.map +1 -1
- package/dist/api/FileRead.d.ts +1 -0
- package/dist/api/FileRead.d.ts.map +1 -1
- package/dist/api/FileWrite.d.ts +2 -0
- package/dist/api/FileWrite.d.ts.map +1 -1
- package/dist/api/FirmwareUpdate.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV2.d.ts +2 -2
- package/dist/api/FirmwareUpdateV2.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV3.d.ts.map +1 -1
- package/dist/api/FirmwareUpdateV4.d.ts +23 -14
- package/dist/api/FirmwareUpdateV4.d.ts.map +1 -1
- package/dist/api/GetDeviceState.d.ts +8 -0
- package/dist/api/GetDeviceState.d.ts.map +1 -0
- package/dist/api/GetFeatures.d.ts +1 -1
- package/dist/api/GetFeatures.d.ts.map +1 -1
- package/dist/api/GetOnekeyFeatures.d.ts.map +1 -1
- package/dist/api/GetPassphraseState.d.ts +2 -6
- package/dist/api/GetPassphraseState.d.ts.map +1 -1
- package/dist/api/OpenWalletSession.d.ts +8 -0
- package/dist/api/OpenWalletSession.d.ts.map +1 -0
- package/dist/api/PathInfo.d.ts +1 -0
- package/dist/api/PathInfo.d.ts.map +1 -1
- package/dist/api/PromptWebDeviceAccess.d.ts.map +1 -1
- package/dist/api/SearchDevices.d.ts +3 -0
- package/dist/api/SearchDevices.d.ts.map +1 -1
- package/dist/api/UploadPortfolio.d.ts +17 -0
- package/dist/api/UploadPortfolio.d.ts.map +1 -0
- package/dist/api/alephium/AlephiumGetAddress.d.ts.map +1 -1
- package/dist/api/alephium/AlephiumSignMessage.d.ts.map +1 -1
- package/dist/api/alephium/AlephiumSignTransaction.d.ts.map +1 -1
- package/dist/api/algo/AlgoGetAddress.d.ts +1 -0
- package/dist/api/algo/AlgoGetAddress.d.ts.map +1 -1
- package/dist/api/algo/AlgoSignTransaction.d.ts +1 -0
- package/dist/api/algo/AlgoSignTransaction.d.ts.map +1 -1
- package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts +1 -0
- package/dist/api/allnetwork/AllNetworkGetAddressBase.d.ts.map +1 -1
- package/dist/api/aptos/AptosGetAddress.d.ts +1 -0
- package/dist/api/aptos/AptosGetAddress.d.ts.map +1 -1
- package/dist/api/aptos/AptosGetPublicKey.d.ts +1 -0
- package/dist/api/aptos/AptosGetPublicKey.d.ts.map +1 -1
- package/dist/api/aptos/AptosSignInMessage.d.ts +1 -0
- package/dist/api/aptos/AptosSignInMessage.d.ts.map +1 -1
- package/dist/api/aptos/AptosSignMessage.d.ts +1 -0
- package/dist/api/aptos/AptosSignMessage.d.ts.map +1 -1
- package/dist/api/aptos/AptosSignTransaction.d.ts +1 -0
- package/dist/api/aptos/AptosSignTransaction.d.ts.map +1 -1
- package/dist/api/benfen/BenfenGetAddress.d.ts.map +1 -1
- package/dist/api/benfen/BenfenGetPublicKey.d.ts.map +1 -1
- package/dist/api/benfen/BenfenSignMessage.d.ts.map +1 -1
- package/dist/api/benfen/BenfenSignTransaction.d.ts.map +1 -1
- package/dist/api/btc/BTCGetAddress.d.ts +1 -0
- package/dist/api/btc/BTCGetAddress.d.ts.map +1 -1
- package/dist/api/btc/BTCGetPublicKey.d.ts +1 -0
- package/dist/api/btc/BTCGetPublicKey.d.ts.map +1 -1
- package/dist/api/btc/BTCSignMessage.d.ts +1 -0
- package/dist/api/btc/BTCSignMessage.d.ts.map +1 -1
- package/dist/api/btc/BTCSignPsbt.d.ts +1 -0
- package/dist/api/btc/BTCSignPsbt.d.ts.map +1 -1
- package/dist/api/btc/BTCSignTransaction.d.ts +1 -0
- package/dist/api/btc/BTCSignTransaction.d.ts.map +1 -1
- package/dist/api/btc/BTCVerifyMessage.d.ts +1 -0
- package/dist/api/btc/BTCVerifyMessage.d.ts.map +1 -1
- package/dist/api/btc/helpers/versionLimit.d.ts +2 -0
- package/dist/api/btc/helpers/versionLimit.d.ts.map +1 -1
- package/dist/api/cardano/CardanoGetAddress.d.ts +1 -0
- package/dist/api/cardano/CardanoGetAddress.d.ts.map +1 -1
- package/dist/api/cardano/CardanoGetPublicKey.d.ts +1 -0
- package/dist/api/cardano/CardanoGetPublicKey.d.ts.map +1 -1
- package/dist/api/cardano/CardanoSignMessage.d.ts +1 -0
- package/dist/api/cardano/CardanoSignMessage.d.ts.map +1 -1
- package/dist/api/cardano/CardanoSignTransaction.d.ts +1 -0
- package/dist/api/cardano/CardanoSignTransaction.d.ts.map +1 -1
- package/dist/api/conflux/ConfluxGetAddress.d.ts +2 -0
- package/dist/api/conflux/ConfluxGetAddress.d.ts.map +1 -1
- package/dist/api/conflux/ConfluxSignMessage.d.ts +2 -0
- package/dist/api/conflux/ConfluxSignMessage.d.ts.map +1 -1
- package/dist/api/conflux/ConfluxSignMessageCIP23.d.ts +2 -0
- package/dist/api/conflux/ConfluxSignMessageCIP23.d.ts.map +1 -1
- package/dist/api/conflux/ConfluxSignTransaction.d.ts +2 -0
- package/dist/api/conflux/ConfluxSignTransaction.d.ts.map +1 -1
- package/dist/api/cosmos/CosmosGetAddress.d.ts +1 -0
- package/dist/api/cosmos/CosmosGetAddress.d.ts.map +1 -1
- package/dist/api/cosmos/CosmosGetPublicKey.d.ts +1 -0
- package/dist/api/cosmos/CosmosGetPublicKey.d.ts.map +1 -1
- package/dist/api/cosmos/CosmosSignTransaction.d.ts +1 -0
- package/dist/api/cosmos/CosmosSignTransaction.d.ts.map +1 -1
- package/dist/api/device/DeviceCancel.d.ts +1 -0
- package/dist/api/device/DeviceCancel.d.ts.map +1 -1
- package/dist/api/device/DeviceChangePin.d.ts +1 -0
- package/dist/api/device/DeviceChangePin.d.ts.map +1 -1
- package/dist/api/device/DeviceFullyUploadResource.d.ts +1 -2
- package/dist/api/device/DeviceFullyUploadResource.d.ts.map +1 -1
- package/dist/api/device/DeviceLock.d.ts +1 -0
- package/dist/api/device/DeviceLock.d.ts.map +1 -1
- package/dist/api/device/DeviceRebootToBoardloader.d.ts +1 -0
- package/dist/api/device/DeviceRebootToBoardloader.d.ts.map +1 -1
- package/dist/api/device/DeviceRebootToBootloader.d.ts +1 -0
- package/dist/api/device/DeviceRebootToBootloader.d.ts.map +1 -1
- package/dist/api/device/DeviceSettings.d.ts +1 -0
- package/dist/api/device/DeviceSettings.d.ts.map +1 -1
- package/dist/api/device/DeviceSupportFeatures.d.ts +1 -0
- package/dist/api/device/DeviceSupportFeatures.d.ts.map +1 -1
- package/dist/api/device/DeviceUnlock.d.ts +1 -0
- package/dist/api/device/DeviceUnlock.d.ts.map +1 -1
- package/dist/api/device/DeviceUpdateBootloader.d.ts.map +1 -1
- package/dist/api/device/DeviceWipe.d.ts +1 -0
- package/dist/api/device/DeviceWipe.d.ts.map +1 -1
- package/dist/api/device/PreInitialize.d.ts +1 -0
- package/dist/api/device/PreInitialize.d.ts.map +1 -1
- package/dist/api/dynex/DnxGetAddress.d.ts.map +1 -1
- package/dist/api/dynex/DnxSignTransaction.d.ts.map +1 -1
- package/dist/api/evm/EVMGetAddress.d.ts +1 -0
- package/dist/api/evm/EVMGetAddress.d.ts.map +1 -1
- package/dist/api/evm/EVMGetPublicKey.d.ts +1 -0
- package/dist/api/evm/EVMGetPublicKey.d.ts.map +1 -1
- package/dist/api/evm/EVMSignMessage.d.ts +1 -0
- package/dist/api/evm/EVMSignMessage.d.ts.map +1 -1
- package/dist/api/evm/EVMSignMessageEIP712.d.ts.map +1 -1
- package/dist/api/evm/EVMSignTransaction.d.ts +1 -0
- package/dist/api/evm/EVMSignTransaction.d.ts.map +1 -1
- package/dist/api/evm/EVMSignTypedData.d.ts +1 -0
- package/dist/api/evm/EVMSignTypedData.d.ts.map +1 -1
- package/dist/api/evm/EVMVerifyMessage.d.ts +1 -0
- package/dist/api/evm/EVMVerifyMessage.d.ts.map +1 -1
- package/dist/api/evm/protocol.d.ts +3 -0
- package/dist/api/evm/protocol.d.ts.map +1 -0
- package/dist/api/filecoin/FilecoinGetAddress.d.ts +1 -0
- package/dist/api/filecoin/FilecoinGetAddress.d.ts.map +1 -1
- package/dist/api/filecoin/FilecoinSignTransaction.d.ts +1 -0
- package/dist/api/filecoin/FilecoinSignTransaction.d.ts.map +1 -1
- package/dist/api/firmware/getBinary.d.ts +8 -4
- package/dist/api/firmware/getBinary.d.ts.map +1 -1
- package/dist/api/helpers/filesystemValidation.d.ts +3 -0
- package/dist/api/helpers/filesystemValidation.d.ts.map +1 -1
- package/dist/api/helpers/paramsValidator.d.ts +1 -0
- package/dist/api/helpers/paramsValidator.d.ts.map +1 -1
- package/dist/api/helpers/protocolV2FileWrite.d.ts +35 -0
- package/dist/api/helpers/protocolV2FileWrite.d.ts.map +1 -0
- package/dist/api/index.d.ts +8 -25
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/kaspa/KaspaGetAddress.d.ts +4 -0
- package/dist/api/kaspa/KaspaGetAddress.d.ts.map +1 -1
- package/dist/api/kaspa/KaspaSignTransaction.d.ts +9 -1
- package/dist/api/kaspa/KaspaSignTransaction.d.ts.map +1 -1
- package/dist/api/kaspa/helpers/TransferSerialize.d.ts.map +1 -1
- package/dist/api/lightning/LnurlAuth.d.ts +0 -4
- package/dist/api/lightning/LnurlAuth.d.ts.map +1 -1
- package/dist/api/near/NearGetAddress.d.ts +1 -0
- package/dist/api/near/NearGetAddress.d.ts.map +1 -1
- package/dist/api/near/NearSignTransaction.d.ts +1 -0
- package/dist/api/near/NearSignTransaction.d.ts.map +1 -1
- package/dist/api/nem/NEMGetAddress.d.ts +1 -0
- package/dist/api/nem/NEMGetAddress.d.ts.map +1 -1
- package/dist/api/nem/NEMSignTransaction.d.ts +1 -0
- package/dist/api/nem/NEMSignTransaction.d.ts.map +1 -1
- package/dist/api/neo/NeoGetAddress.d.ts.map +1 -1
- package/dist/api/neo/NeoSignTransaction.d.ts.map +1 -1
- package/dist/api/nervos/NervosGetAddress.d.ts.map +1 -1
- package/dist/api/nervos/NervosSignTransaction.d.ts.map +1 -1
- package/dist/api/nexa/NexaGetAddress.d.ts.map +1 -1
- package/dist/api/nexa/NexaSignTransaction.d.ts +1 -0
- package/dist/api/nexa/NexaSignTransaction.d.ts.map +1 -1
- package/dist/api/nostr/NostrDecryptMessage.d.ts +1 -0
- package/dist/api/nostr/NostrDecryptMessage.d.ts.map +1 -1
- package/dist/api/nostr/NostrEncryptMessage.d.ts +1 -0
- package/dist/api/nostr/NostrEncryptMessage.d.ts.map +1 -1
- package/dist/api/nostr/NostrGetPublicKey.d.ts +1 -0
- package/dist/api/nostr/NostrGetPublicKey.d.ts.map +1 -1
- package/dist/api/nostr/NostrSignEvent.d.ts +1 -0
- package/dist/api/nostr/NostrSignEvent.d.ts.map +1 -1
- package/dist/api/nostr/NostrSignSchnorr.d.ts +1 -0
- package/dist/api/nostr/NostrSignSchnorr.d.ts.map +1 -1
- package/dist/api/polkadot/PolkadotGetAddress.d.ts +1 -0
- package/dist/api/polkadot/PolkadotGetAddress.d.ts.map +1 -1
- package/dist/api/polkadot/PolkadotSignTransaction.d.ts +1 -0
- package/dist/api/polkadot/PolkadotSignTransaction.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceFactoryInfoGet.d.ts +1 -0
- package/dist/api/protocol-v2/DeviceFactoryInfoGet.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceFactoryInfoSet.d.ts +1 -0
- package/dist/api/protocol-v2/DeviceFactoryInfoSet.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceFirmwareUpdate.d.ts +1 -0
- package/dist/api/protocol-v2/DeviceFirmwareUpdate.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceGetFirmwareUpdateStatus.d.ts +4 -2
- package/dist/api/protocol-v2/DeviceGetFirmwareUpdateStatus.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceGetOnboardingStatus.d.ts +7 -0
- package/dist/api/protocol-v2/DeviceGetOnboardingStatus.d.ts.map +1 -0
- package/dist/api/protocol-v2/DeviceInfoGet.d.ts +1 -1
- package/dist/api/protocol-v2/DeviceInfoGet.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceReboot.d.ts +1 -0
- package/dist/api/protocol-v2/DeviceReboot.d.ts.map +1 -1
- package/dist/api/protocol-v2/DeviceStatusGet.d.ts +7 -0
- package/dist/api/protocol-v2/DeviceStatusGet.d.ts.map +1 -0
- package/dist/api/protocol-v2/DeviceUploadNft.d.ts +30 -0
- package/dist/api/protocol-v2/DeviceUploadNft.d.ts.map +1 -0
- package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts +27 -0
- package/dist/api/protocol-v2/DeviceUploadWallpaper.d.ts.map +1 -0
- package/dist/api/protocol-v2/FilesystemFormat.d.ts +1 -0
- package/dist/api/protocol-v2/FilesystemFormat.d.ts.map +1 -1
- package/dist/api/protocol-v2/FilesystemPermissionFix.d.ts +1 -0
- package/dist/api/protocol-v2/FilesystemPermissionFix.d.ts.map +1 -1
- package/dist/api/protocol-v2/Ping.d.ts +3 -0
- package/dist/api/protocol-v2/Ping.d.ts.map +1 -1
- package/dist/api/protocol-v2/ProtocolInfoRequest.d.ts +1 -0
- package/dist/api/protocol-v2/ProtocolInfoRequest.d.ts.map +1 -1
- package/dist/api/protocol-v2/helpers.d.ts +4 -1
- package/dist/api/protocol-v2/helpers.d.ts.map +1 -1
- package/dist/api/scdo/ScdoGetAddress.d.ts.map +1 -1
- package/dist/api/scdo/ScdoSignMessage.d.ts.map +1 -1
- package/dist/api/scdo/ScdoSignTransaction.d.ts.map +1 -1
- package/dist/api/solana/SolGetAddress.d.ts +1 -0
- package/dist/api/solana/SolGetAddress.d.ts.map +1 -1
- package/dist/api/solana/SolSignMessage.d.ts +1 -0
- package/dist/api/solana/SolSignMessage.d.ts.map +1 -1
- package/dist/api/solana/SolSignOffchainMessage.d.ts +1 -0
- package/dist/api/solana/SolSignOffchainMessage.d.ts.map +1 -1
- package/dist/api/solana/SolSignTransaction.d.ts +1 -0
- package/dist/api/solana/SolSignTransaction.d.ts.map +1 -1
- package/dist/api/starcoin/StarcoinGetAddress.d.ts +1 -0
- package/dist/api/starcoin/StarcoinGetAddress.d.ts.map +1 -1
- package/dist/api/starcoin/StarcoinGetPublicKey.d.ts +1 -0
- package/dist/api/starcoin/StarcoinGetPublicKey.d.ts.map +1 -1
- package/dist/api/starcoin/StarcoinSignMessage.d.ts +1 -0
- package/dist/api/starcoin/StarcoinSignMessage.d.ts.map +1 -1
- package/dist/api/starcoin/StarcoinSignTransaction.d.ts +1 -0
- package/dist/api/starcoin/StarcoinSignTransaction.d.ts.map +1 -1
- package/dist/api/starcoin/StarcoinVerifyMessage.d.ts +1 -0
- package/dist/api/starcoin/StarcoinVerifyMessage.d.ts.map +1 -1
- package/dist/api/stellar/StellarGetAddress.d.ts +1 -2
- package/dist/api/stellar/StellarGetAddress.d.ts.map +1 -1
- package/dist/api/stellar/StellarSignTransaction.d.ts +1 -2
- package/dist/api/stellar/StellarSignTransaction.d.ts.map +1 -1
- package/dist/api/sui/SuiGetAddress.d.ts +1 -0
- package/dist/api/sui/SuiGetAddress.d.ts.map +1 -1
- package/dist/api/sui/SuiGetPublicKey.d.ts +1 -0
- package/dist/api/sui/SuiGetPublicKey.d.ts.map +1 -1
- package/dist/api/sui/SuiSignMessage.d.ts +1 -0
- package/dist/api/sui/SuiSignMessage.d.ts.map +1 -1
- package/dist/api/sui/SuiSignTransaction.d.ts +1 -0
- package/dist/api/sui/SuiSignTransaction.d.ts.map +1 -1
- package/dist/api/ton/TonGetAddress.d.ts +1 -0
- package/dist/api/ton/TonGetAddress.d.ts.map +1 -1
- package/dist/api/ton/TonSignData.d.ts +1 -0
- package/dist/api/ton/TonSignData.d.ts.map +1 -1
- package/dist/api/ton/TonSignMessage.d.ts +1 -0
- package/dist/api/ton/TonSignMessage.d.ts.map +1 -1
- package/dist/api/ton/TonSignProof.d.ts +1 -0
- package/dist/api/ton/TonSignProof.d.ts.map +1 -1
- package/dist/api/tron/TronGetAddress.d.ts +1 -0
- package/dist/api/tron/TronGetAddress.d.ts.map +1 -1
- package/dist/api/tron/TronSignMessage.d.ts +5 -0
- package/dist/api/tron/TronSignMessage.d.ts.map +1 -1
- package/dist/api/tron/TronSignTransaction.d.ts +1 -0
- package/dist/api/tron/TronSignTransaction.d.ts.map +1 -1
- package/dist/api/utils.d.ts +2 -1
- package/dist/api/utils.d.ts.map +1 -1
- package/dist/api/xrp/XrpGetAddress.d.ts +1 -0
- package/dist/api/xrp/XrpGetAddress.d.ts.map +1 -1
- package/dist/api/xrp/XrpSignTransaction.d.ts +1 -0
- package/dist/api/xrp/XrpSignTransaction.d.ts.map +1 -1
- package/dist/constants/index.d.ts +1 -1
- package/dist/constants/index.d.ts.map +1 -1
- package/dist/core/RequestQueue.d.ts.map +1 -1
- package/dist/core/deviceEventRegistration.d.ts +13 -0
- package/dist/core/deviceEventRegistration.d.ts.map +1 -0
- package/dist/core/index.d.ts +3 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/data-manager/connectSettings.d.ts.map +1 -1
- package/dist/device/Device.d.ts +64 -16
- package/dist/device/Device.d.ts.map +1 -1
- package/dist/device/DeviceCommands.d.ts +8 -6
- package/dist/device/DeviceCommands.d.ts.map +1 -1
- package/dist/device/DeviceConnector.d.ts +1 -1
- package/dist/device/DeviceConnector.d.ts.map +1 -1
- package/dist/device/DeviceFeaturesState.d.ts +3 -0
- package/dist/device/DeviceFeaturesState.d.ts.map +1 -0
- package/dist/device/DevicePool.d.ts +5 -2
- package/dist/device/DevicePool.d.ts.map +1 -1
- package/dist/device/DeviceStateMapper.d.ts +13 -0
- package/dist/device/DeviceStateMapper.d.ts.map +1 -0
- package/dist/device/DeviceStateProjector.d.ts +7 -0
- package/dist/device/DeviceStateProjector.d.ts.map +1 -0
- package/dist/device/DeviceStateStore.d.ts +21 -0
- package/dist/device/DeviceStateStore.d.ts.map +1 -0
- package/dist/device/DeviceWalletSessionStore.d.ts +27 -0
- package/dist/device/DeviceWalletSessionStore.d.ts.map +1 -0
- package/dist/device/cloneDeviceState.d.ts +2 -0
- package/dist/device/cloneDeviceState.d.ts.map +1 -0
- package/dist/device/deviceIdentity.d.ts +5 -0
- package/dist/device/deviceIdentity.d.ts.map +1 -0
- package/dist/deviceProfile/buildDeviceFeatures.d.ts +9 -3
- package/dist/deviceProfile/buildDeviceFeatures.d.ts.map +1 -1
- package/dist/deviceProfile/index.d.ts +0 -1
- package/dist/deviceProfile/index.d.ts.map +1 -1
- package/dist/deviceProfile/protocolV2DeviceIdentity.d.ts +7 -0
- package/dist/deviceProfile/protocolV2DeviceIdentity.d.ts.map +1 -0
- package/dist/events/device.d.ts +16 -2
- package/dist/events/device.d.ts.map +1 -1
- package/dist/events/logBlockEvent.d.ts +2 -0
- package/dist/events/logBlockEvent.d.ts.map +1 -1
- package/dist/events/ui-request.d.ts +46 -4
- package/dist/events/ui-request.d.ts.map +1 -1
- package/dist/index.d.ts +1442 -712
- package/dist/index.js +7497 -3705
- package/dist/inject.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/deviceSession.d.ts +7 -0
- package/dist/protocols/protocol-v2/deviceSession.d.ts.map +1 -0
- package/dist/protocols/protocol-v2/features.d.ts +25 -17
- package/dist/protocols/protocol-v2/features.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/firmware.d.ts +1 -0
- package/dist/protocols/protocol-v2/firmware.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/index.d.ts +3 -2
- package/dist/protocols/protocol-v2/index.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/settingsUnlockPolicy.d.ts +17 -0
- package/dist/protocols/protocol-v2/settingsUnlockPolicy.d.ts.map +1 -0
- package/dist/protocols/protocol-v2/uiInteraction.d.ts +39 -0
- package/dist/protocols/protocol-v2/uiInteraction.d.ts.map +1 -0
- package/dist/protocols/protocol-v2/unlockPolicy.d.ts +2 -0
- package/dist/protocols/protocol-v2/unlockPolicy.d.ts.map +1 -0
- package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts +22 -0
- package/dist/protocols/protocol-v2/unlockPolicyRunner.d.ts.map +1 -0
- package/dist/protocols/protocol-v2/walletSession.d.ts +25 -0
- package/dist/protocols/protocol-v2/walletSession.d.ts.map +1 -0
- package/dist/types/api/checkAllFirmwareRelease.d.ts +25 -4
- package/dist/types/api/checkAllFirmwareRelease.d.ts.map +1 -1
- package/dist/types/api/deviceSettings.d.ts +11 -2
- package/dist/types/api/deviceSettings.d.ts.map +1 -1
- package/dist/types/api/deviceUnlock.d.ts +1 -1
- package/dist/types/api/deviceUnlock.d.ts.map +1 -1
- package/dist/types/api/export.d.ts +3 -2
- package/dist/types/api/export.d.ts.map +1 -1
- package/dist/types/api/firmwareUpdate.d.ts +6 -1
- package/dist/types/api/firmwareUpdate.d.ts.map +1 -1
- package/dist/types/api/getDeviceState.d.ts +12 -0
- package/dist/types/api/getDeviceState.d.ts.map +1 -0
- package/dist/types/api/getFeatures.d.ts.map +1 -1
- package/dist/types/api/getOnekeyFeatures.d.ts.map +1 -1
- package/dist/types/api/getPassphraseState.d.ts +2 -10
- package/dist/types/api/getPassphraseState.d.ts.map +1 -1
- package/dist/types/api/index.d.ts +19 -30
- package/dist/types/api/index.d.ts.map +1 -1
- package/dist/types/api/kaspaSignTransaction.d.ts +42 -4
- package/dist/types/api/kaspaSignTransaction.d.ts.map +1 -1
- package/dist/types/api/openWalletSession.d.ts +35 -0
- package/dist/types/api/openWalletSession.d.ts.map +1 -0
- package/dist/types/api/protocolV2.d.ts +18 -84
- package/dist/types/api/protocolV2.d.ts.map +1 -1
- package/dist/types/api/sessionCache.d.ts +13 -0
- package/dist/types/api/sessionCache.d.ts.map +1 -0
- package/dist/types/device.d.ts +132 -8
- package/dist/types/device.d.ts.map +1 -1
- package/dist/types/params.d.ts.map +1 -1
- package/dist/types/settings.d.ts +7 -14
- package/dist/types/settings.d.ts.map +1 -1
- package/dist/utils/assets.d.ts +2 -1
- package/dist/utils/assets.d.ts.map +1 -1
- package/dist/utils/deviceFeaturesCompat.d.ts +13 -0
- package/dist/utils/deviceFeaturesCompat.d.ts.map +1 -0
- package/dist/utils/deviceFeaturesUtils.d.ts +8 -3
- package/dist/utils/deviceFeaturesUtils.d.ts.map +1 -1
- package/dist/utils/deviceInfoUtils.d.ts +9 -9
- package/dist/utils/deviceInfoUtils.d.ts.map +1 -1
- package/dist/utils/deviceSettings.d.ts +38 -7
- package/dist/utils/deviceSettings.d.ts.map +1 -1
- package/dist/utils/deviceVersionUtils.d.ts +7 -5
- package/dist/utils/deviceVersionUtils.d.ts.map +1 -1
- package/dist/utils/homescreen.d.ts +4 -0
- package/dist/utils/homescreen.d.ts.map +1 -1
- package/dist/utils/index.d.ts +6 -3
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/networkUtils.d.ts +10 -1
- package/dist/utils/networkUtils.d.ts.map +1 -1
- package/dist/utils/patch.d.ts +1 -1
- package/dist/utils/patch.d.ts.map +1 -1
- package/dist/utils/pro2Nft.d.ts +29 -0
- package/dist/utils/pro2Nft.d.ts.map +1 -0
- package/dist/utils/pro2Wallpaper.d.ts +22 -0
- package/dist/utils/pro2Wallpaper.d.ts.map +1 -0
- package/dist/utils/tracing.d.ts.map +1 -1
- package/dist/utils/uiProgressThrottle.d.ts +3 -0
- package/dist/utils/uiProgressThrottle.d.ts.map +1 -0
- package/package.json +4 -4
- package/src/api/BaseMethod.ts +53 -20
- package/src/api/CheckAllFirmwareRelease.ts +296 -1
- package/src/api/CheckBootloaderRelease.ts +1 -2
- package/src/api/CheckFirmwareRelease.ts +1 -2
- package/src/api/CipherKeyValue.ts +4 -0
- package/src/api/ClearSessionCache.ts +32 -0
- package/src/api/DirList.ts +9 -4
- package/src/api/DirMake.ts +7 -4
- package/src/api/DirRemove.ts +7 -4
- package/src/api/FileDelete.ts +7 -4
- package/src/api/FileRead.ts +15 -9
- package/src/api/FileWrite.ts +26 -181
- package/src/api/FirmwareUpdate.ts +11 -12
- package/src/api/FirmwareUpdateV2.ts +132 -52
- package/src/api/FirmwareUpdateV3.ts +3 -11
- package/src/api/FirmwareUpdateV4.ts +693 -535
- package/src/api/GetDeviceState.ts +59 -0
- package/src/api/GetFeatures.ts +6 -4
- package/src/api/GetOnekeyFeatures.ts +1 -75
- package/src/api/GetPassphraseState.ts +36 -21
- package/src/api/OpenWalletSession.ts +251 -0
- package/src/api/PathInfo.ts +9 -4
- package/src/api/PromptWebDeviceAccess.ts +2 -7
- package/src/api/SearchDevices.ts +29 -4
- package/src/api/UploadPortfolio.ts +40 -0
- package/src/api/alephium/AlephiumGetAddress.ts +0 -4
- package/src/api/alephium/AlephiumSignMessage.ts +0 -4
- package/src/api/alephium/AlephiumSignTransaction.ts +2 -6
- package/src/api/algo/AlgoGetAddress.ts +4 -0
- package/src/api/algo/AlgoSignTransaction.ts +4 -0
- package/src/api/allnetwork/AllNetworkGetAddressBase.ts +41 -32
- package/src/api/aptos/AptosGetAddress.ts +4 -0
- package/src/api/aptos/AptosGetPublicKey.ts +4 -0
- package/src/api/aptos/AptosSignInMessage.ts +4 -0
- package/src/api/aptos/AptosSignMessage.ts +4 -0
- package/src/api/aptos/AptosSignTransaction.ts +4 -0
- package/src/api/benfen/BenfenGetAddress.ts +11 -7
- package/src/api/benfen/BenfenGetPublicKey.ts +0 -4
- package/src/api/benfen/BenfenSignMessage.ts +0 -4
- package/src/api/benfen/BenfenSignTransaction.ts +0 -4
- package/src/api/btc/BTCGetAddress.ts +8 -1
- package/src/api/btc/BTCGetPublicKey.ts +9 -2
- package/src/api/btc/BTCSignMessage.ts +8 -1
- package/src/api/btc/BTCSignPsbt.ts +4 -0
- package/src/api/btc/BTCSignTransaction.ts +8 -1
- package/src/api/btc/BTCVerifyMessage.ts +8 -1
- package/src/api/btc/helpers/versionLimit.ts +7 -4
- package/src/api/cardano/CardanoGetAddress.ts +4 -0
- package/src/api/cardano/CardanoGetPublicKey.ts +4 -0
- package/src/api/cardano/CardanoSignMessage.ts +5 -1
- package/src/api/cardano/CardanoSignTransaction.ts +5 -1
- package/src/api/conflux/ConfluxGetAddress.ts +6 -0
- package/src/api/conflux/ConfluxSignMessage.ts +6 -0
- package/src/api/conflux/ConfluxSignMessageCIP23.ts +6 -0
- package/src/api/conflux/ConfluxSignTransaction.ts +8 -5
- package/src/api/cosmos/CosmosGetAddress.ts +4 -0
- package/src/api/cosmos/CosmosGetPublicKey.ts +4 -0
- package/src/api/cosmos/CosmosSignTransaction.ts +4 -0
- package/src/api/device/DeviceCancel.ts +5 -0
- package/src/api/device/DeviceChangePin.ts +28 -0
- package/src/api/device/DeviceFullyUploadResource.ts +4 -5
- package/src/api/device/DeviceLock.ts +5 -0
- package/src/api/device/DeviceRebootToBoardloader.ts +5 -0
- package/src/api/device/DeviceRebootToBootloader.ts +5 -0
- package/src/api/device/DeviceSettings.ts +194 -1
- package/src/api/device/DeviceSupportFeatures.ts +4 -0
- package/src/api/device/DeviceUnlock.ts +14 -1
- package/src/api/device/DeviceUpdateBootloader.ts +1 -2
- package/src/api/device/DeviceWipe.ts +25 -0
- package/src/api/device/PreInitialize.ts +4 -0
- package/src/api/dynex/DnxGetAddress.ts +0 -6
- package/src/api/dynex/DnxSignTransaction.ts +0 -6
- package/src/api/evm/EVMGetAddress.ts +6 -2
- package/src/api/evm/EVMGetPublicKey.ts +6 -2
- package/src/api/evm/EVMSignMessage.ts +6 -2
- package/src/api/evm/EVMSignMessageEIP712.ts +1 -11
- package/src/api/evm/EVMSignTransaction.ts +6 -2
- package/src/api/evm/EVMSignTypedData.ts +42 -50
- package/src/api/evm/EVMVerifyMessage.ts +6 -2
- package/src/api/evm/legacyV1/getAddress.ts +2 -2
- package/src/api/evm/legacyV1/getPublicKey.ts +2 -2
- package/src/api/evm/legacyV1/signMessage.ts +2 -2
- package/src/api/evm/legacyV1/signTypedData.ts +2 -2
- package/src/api/evm/legacyV1/signTypedHash.ts +2 -2
- package/src/api/evm/legacyV1/verifyMessage.ts +2 -2
- package/src/api/evm/protocol.ts +6 -0
- package/src/api/filecoin/FilecoinGetAddress.ts +4 -0
- package/src/api/filecoin/FilecoinSignTransaction.ts +4 -0
- package/src/api/firmware/FirmwareUpdateBaseMethod.ts +3 -3
- package/src/api/firmware/getBinary.ts +8 -3
- package/src/api/helpers/batchGetPublickeys.ts +2 -2
- package/src/api/helpers/filesystemValidation.ts +61 -0
- package/src/api/helpers/paramsValidator.ts +1 -1
- package/src/api/helpers/protocolV2FileWrite.ts +206 -0
- package/src/api/index.ts +9 -26
- package/src/api/kaspa/KaspaGetAddress.ts +7 -0
- package/src/api/kaspa/KaspaSignTransaction.ts +380 -29
- package/src/api/kaspa/helpers/TransferSerialize.ts +17 -7
- package/src/api/lightning/LnurlAuth.ts +0 -4
- package/src/api/near/NearGetAddress.ts +4 -0
- package/src/api/near/NearSignTransaction.ts +4 -0
- package/src/api/nem/NEMGetAddress.ts +4 -0
- package/src/api/nem/NEMSignTransaction.ts +4 -0
- package/src/api/neo/NeoGetAddress.ts +0 -4
- package/src/api/neo/NeoSignTransaction.ts +0 -4
- package/src/api/nervos/NervosGetAddress.ts +0 -4
- package/src/api/nervos/NervosSignTransaction.ts +2 -6
- package/src/api/nexa/NexaGetAddress.ts +0 -4
- package/src/api/nexa/NexaSignTransaction.ts +3 -5
- package/src/api/nostr/NostrDecryptMessage.ts +4 -0
- package/src/api/nostr/NostrEncryptMessage.ts +4 -0
- package/src/api/nostr/NostrGetPublicKey.ts +4 -0
- package/src/api/nostr/NostrSignEvent.ts +4 -0
- package/src/api/nostr/NostrSignSchnorr.ts +4 -0
- package/src/api/polkadot/PolkadotGetAddress.ts +4 -0
- package/src/api/polkadot/PolkadotSignTransaction.ts +4 -0
- package/src/api/protocol-v2/DeviceFactoryInfoGet.ts +5 -2
- package/src/api/protocol-v2/DeviceFactoryInfoSet.ts +5 -2
- package/src/api/protocol-v2/DeviceFirmwareUpdate.ts +8 -5
- package/src/api/protocol-v2/DeviceGetFirmwareUpdateStatus.ts +43 -5
- package/src/api/protocol-v2/DeviceGetOnboardingStatus.ts +21 -0
- package/src/api/protocol-v2/DeviceInfoGet.ts +8 -15
- package/src/api/protocol-v2/DeviceReboot.ts +7 -3
- package/src/api/protocol-v2/DeviceStatusGet.ts +19 -0
- package/src/api/protocol-v2/DeviceUploadNft.ts +166 -0
- package/src/api/protocol-v2/DeviceUploadWallpaper.ts +134 -0
- package/src/api/protocol-v2/FilesystemFormat.ts +9 -3
- package/src/api/protocol-v2/FilesystemPermissionFix.ts +5 -2
- package/src/api/protocol-v2/Ping.ts +37 -3
- package/src/api/protocol-v2/ProtocolInfoRequest.ts +8 -3
- package/src/api/protocol-v2/helpers.ts +21 -16
- package/src/api/scdo/ScdoGetAddress.ts +0 -4
- package/src/api/scdo/ScdoSignMessage.ts +0 -4
- package/src/api/scdo/ScdoSignTransaction.ts +0 -4
- package/src/api/solana/SolGetAddress.ts +4 -0
- package/src/api/solana/SolSignMessage.ts +4 -0
- package/src/api/solana/SolSignOffchainMessage.ts +4 -0
- package/src/api/solana/SolSignTransaction.ts +4 -0
- package/src/api/starcoin/StarcoinGetAddress.ts +4 -0
- package/src/api/starcoin/StarcoinGetPublicKey.ts +4 -0
- package/src/api/starcoin/StarcoinSignMessage.ts +4 -0
- package/src/api/starcoin/StarcoinSignTransaction.ts +4 -0
- package/src/api/starcoin/StarcoinVerifyMessage.ts +4 -0
- package/src/api/stellar/StellarGetAddress.ts +1 -10
- package/src/api/stellar/StellarSignTransaction.ts +1 -14
- package/src/api/sui/SuiGetAddress.ts +4 -0
- package/src/api/sui/SuiGetPublicKey.ts +4 -0
- package/src/api/sui/SuiSignMessage.ts +4 -0
- package/src/api/sui/SuiSignTransaction.ts +4 -0
- package/src/api/ton/TonGetAddress.ts +4 -0
- package/src/api/ton/TonSignData.ts +5 -1
- package/src/api/ton/TonSignMessage.ts +4 -0
- package/src/api/ton/TonSignProof.ts +4 -0
- package/src/api/tron/TronGetAddress.ts +4 -0
- package/src/api/tron/TronSignMessage.ts +18 -7
- package/src/api/tron/TronSignTransaction.ts +4 -0
- package/src/api/utils.ts +7 -3
- package/src/api/xrp/XrpGetAddress.ts +4 -0
- package/src/api/xrp/XrpSignTransaction.ts +5 -1
- package/src/constants/index.ts +1 -4
- package/src/core/RequestQueue.ts +1 -0
- package/src/core/deviceEventRegistration.ts +27 -0
- package/src/core/index.ts +274 -120
- package/src/data/messages/messages-protocol-v2.json +1161 -477
- package/src/data/messages/messages.json +286 -1
- package/src/data-manager/DataManager.ts +6 -6
- package/src/data-manager/TransportManager.ts +1 -1
- package/src/data-manager/connectSettings.ts +4 -0
- package/src/device/Device.ts +820 -282
- package/src/device/DeviceCommands.ts +166 -158
- package/src/device/DeviceConnector.ts +10 -7
- package/src/device/DeviceFeaturesState.ts +25 -0
- package/src/device/DevicePool.ts +66 -16
- package/src/device/DeviceStateMapper.ts +374 -0
- package/src/device/DeviceStateProjector.ts +94 -0
- package/src/device/DeviceStateStore.ts +201 -0
- package/src/device/DeviceWalletSessionStore.ts +144 -0
- package/src/device/cloneDeviceState.ts +39 -0
- package/src/device/deviceIdentity.ts +18 -0
- package/src/deviceProfile/buildDeviceFeatures.ts +224 -190
- package/src/deviceProfile/index.ts +0 -1
- package/src/deviceProfile/protocolV2DeviceIdentity.ts +32 -0
- package/src/events/device.ts +22 -1
- package/src/events/logBlockEvent.ts +80 -2
- package/src/events/ui-request.ts +57 -4
- package/src/inject.ts +16 -41
- package/src/protocols/protocol-v2/deviceSession.ts +24 -0
- package/src/protocols/protocol-v2/features.ts +103 -32
- package/src/protocols/protocol-v2/firmware.ts +2 -1
- package/src/protocols/protocol-v2/index.ts +8 -1
- package/src/protocols/protocol-v2/settingsUnlockPolicy.ts +65 -0
- package/src/protocols/protocol-v2/uiInteraction.ts +236 -0
- package/src/protocols/protocol-v2/unlockPolicy.ts +1 -0
- package/src/protocols/protocol-v2/unlockPolicyRunner.ts +117 -0
- package/src/protocols/protocol-v2/walletSession.ts +360 -0
- package/src/types/api/checkAllFirmwareRelease.ts +46 -4
- package/src/types/api/deviceSettings.ts +26 -2
- package/src/types/api/deviceUnlock.ts +1 -1
- package/src/types/api/export.ts +8 -0
- package/src/types/api/firmwareUpdate.ts +23 -5
- package/src/types/api/getDeviceState.ts +19 -0
- package/src/types/api/getFeatures.ts +3 -0
- package/src/types/api/getOnekeyFeatures.ts +3 -0
- package/src/types/api/getPassphraseState.ts +9 -11
- package/src/types/api/index.ts +27 -64
- package/src/types/api/kaspaSignTransaction.ts +60 -4
- package/src/types/api/openWalletSession.ts +54 -0
- package/src/types/api/protocolV2.ts +33 -139
- package/src/types/api/sessionCache.ts +19 -0
- package/src/types/device.ts +185 -7
- package/src/types/params.ts +3 -2
- package/src/types/settings.ts +17 -16
- package/src/utils/assets.ts +4 -1
- package/src/utils/deviceFeaturesCompat.ts +180 -0
- package/src/utils/deviceFeaturesUtils.ts +56 -45
- package/src/utils/deviceInfoUtils.ts +27 -69
- package/src/utils/deviceSettings.ts +171 -39
- package/src/utils/deviceVersionUtils.ts +25 -44
- package/src/utils/findDefectiveBatchDevice.ts +3 -3
- package/src/utils/homescreen.ts +36 -0
- package/src/utils/index.ts +27 -3
- package/src/utils/networkUtils.ts +274 -16
- package/src/utils/pro2Nft.ts +91 -0
- package/src/utils/pro2Wallpaper.ts +130 -0
- package/src/utils/tracing.ts +3 -1
- package/src/utils/uiProgressThrottle.ts +63 -0
- package/tsconfig.type-tests.json +12 -0
- package/dist/api/GetDeviceInfo.d.ts +0 -9
- package/dist/api/GetDeviceInfo.d.ts.map +0 -1
- package/dist/api/protocol-v2/FilesystemDiskControl.d.ts +0 -13
- package/dist/api/protocol-v2/FilesystemDiskControl.d.ts.map +0 -1
- package/dist/deviceProfile/buildDeviceProfile.d.ts +0 -21
- package/dist/deviceProfile/buildDeviceProfile.d.ts.map +0 -1
- package/dist/types/api/getDeviceInfo.d.ts +0 -87
- package/dist/types/api/getDeviceInfo.d.ts.map +0 -1
- package/src/api/GetDeviceInfo.ts +0 -145
- package/src/api/protocol-v2/FilesystemDiskControl.ts +0 -50
- package/src/deviceProfile/buildDeviceProfile.ts +0 -352
- package/src/types/api/getDeviceInfo.ts +0 -101
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import { ERRORS, HardwareError, HardwareErrorCode, wait } from '@onekeyfe/hd-shared';
|
|
1
|
+
import { EDeviceType, ERRORS, HardwareError, HardwareErrorCode, wait } from '@onekeyfe/hd-shared';
|
|
2
2
|
import {
|
|
3
3
|
DeviceRebootType,
|
|
4
4
|
PROTOCOL_V2_BLE_FILE_CHUNK_SIZE,
|
|
5
|
+
PROTOCOL_V2_BLE_FILE_READ_CHUNK_SIZE,
|
|
5
6
|
PROTOCOL_V2_WEBUSB_FILE_CHUNK_SIZE,
|
|
6
7
|
} from '@onekeyfe/hd-transport';
|
|
8
|
+
import { sha256 } from '@noble/hashes/sha256';
|
|
7
9
|
|
|
8
10
|
import { FirmwareUpdateTipMessage, UI_REQUEST } from '../events/ui-request';
|
|
11
|
+
import { validateProtocolV2FilesystemPath } from './helpers/filesystemValidation';
|
|
9
12
|
import { validateParams } from './helpers/paramsValidator';
|
|
10
13
|
import {
|
|
11
14
|
LoggerNames,
|
|
@@ -25,20 +28,19 @@ import {
|
|
|
25
28
|
} from '../protocols/protocol-v2';
|
|
26
29
|
import { requestProtocolV2DeviceInfo } from '../protocols/protocol-v2/features';
|
|
27
30
|
import {
|
|
28
|
-
PROTOCOL_V2_FIRMWARE_UPDATE_RESPONSE_TYPES,
|
|
29
31
|
getProtocolV2UnknownErrorText,
|
|
30
32
|
isProtocolV2DeviceDisconnectedError,
|
|
31
33
|
} from './protocol-v2/helpers';
|
|
32
34
|
|
|
33
|
-
import type { FirmwareUpdateV4Params } from '../types/api/firmwareUpdate';
|
|
35
|
+
import type { FirmwareUpdateV4Params, FirmwareUpdateV4Target } from '../types/api/firmwareUpdate';
|
|
34
36
|
import type { EFirmwareType } from '@onekeyfe/hd-shared';
|
|
37
|
+
import type { ProtocolV2DeviceInfo } from '@onekeyfe/hd-transport';
|
|
35
38
|
import type { PROTO } from '../constants';
|
|
36
39
|
import type { TypedResponseMessage } from '../device/DeviceCommands';
|
|
37
40
|
import type {
|
|
38
41
|
Features,
|
|
39
42
|
IFirmwareReleaseInfo,
|
|
40
43
|
IProtocolV2FirmwareComponent,
|
|
41
|
-
IProtocolV2ResourceManifestPackage,
|
|
42
44
|
IVersionArray,
|
|
43
45
|
} from '../types';
|
|
44
46
|
|
|
@@ -46,20 +48,22 @@ const Log = getLogger(LoggerNames.Method);
|
|
|
46
48
|
|
|
47
49
|
const SESSION_ERROR = 'session not found';
|
|
48
50
|
const PROTOCOL_V2_BOOTLOADER_RECONNECT_TIMEOUT = 60 * 1000;
|
|
51
|
+
const PROTOCOL_V2_FINAL_RECONNECT_TIMEOUT = 2 * 60 * 1000;
|
|
49
52
|
const PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT = 5 * 1000;
|
|
50
|
-
const PROTOCOL_V2_START_UPDATE_TIMEOUT = 60 * 1000;
|
|
53
|
+
const PROTOCOL_V2_START_UPDATE_TIMEOUT = 3 * 60 * 1000;
|
|
51
54
|
const PROTOCOL_V2_INSTALL_TIMEOUT = 5 * 60 * 1000;
|
|
52
55
|
const PROTOCOL_V2_TARGET_STATUS_PENDING = 0;
|
|
53
56
|
const PROTOCOL_V2_TARGET_STATUS_IN_PROGRESS = 1;
|
|
54
57
|
const PROTOCOL_V2_TARGET_STATUS_FINISHED = 2;
|
|
55
58
|
const PROTOCOL_V2_TARGET_STATUS_FAILED_MIN = 3;
|
|
56
59
|
const PROTOCOL_V2_CONNECT_PROTOCOL = 'V2';
|
|
57
|
-
const PROTOCOL_V2_FIRMWARE_STAGING_VOLUME = '
|
|
60
|
+
const PROTOCOL_V2_FIRMWARE_STAGING_VOLUME = 'vol0:/';
|
|
58
61
|
const PROTOCOL_V2_MIN_FILE_CHUNK_SIZE = 64;
|
|
59
62
|
const PROTOCOL_V2_CONNECT_RETRY_COUNT = 10;
|
|
60
63
|
const PROTOCOL_V2_CONNECT_POLL_INTERVAL = 500;
|
|
61
64
|
const PROTOCOL_V2_CONNECT_SINGLE_TIMEOUT = 75 * 1000;
|
|
62
65
|
const PROTOCOL_V2_DEVICE_INFO_READY_TIMEOUT = 60 * 1000;
|
|
66
|
+
const PROTOCOL_V2_FILE_TRANSFER_RETRY_COUNT = 3;
|
|
63
67
|
const PROTOCOL_V2_OKPP_HEADER_SIZE = 0x52a0;
|
|
64
68
|
const PROTOCOL_V2_OKPP_PAYLOAD_HASH_OFFSET = 0x200;
|
|
65
69
|
const PROTOCOL_V2_OKPP_HEADER_HASH_OFFSET = 0x240;
|
|
@@ -94,12 +98,34 @@ type ProtocolV2FirmwareUpdateStatusTarget = {
|
|
|
94
98
|
path?: string;
|
|
95
99
|
};
|
|
96
100
|
|
|
97
|
-
type ProtocolV2FirmwareUpdateStartResponse =
|
|
98
|
-
| TypedResponseMessage<'Success'>
|
|
99
|
-
| TypedResponseMessage<'DeviceFirmwareUpdateStatus'>
|
|
100
|
-
| undefined;
|
|
101
|
+
type ProtocolV2FirmwareUpdateStartResponse = TypedResponseMessage<'Success'>;
|
|
101
102
|
|
|
102
103
|
type ProtocolV2TargetBinary = { fileName: string; binary: ArrayBuffer; targetId: number };
|
|
104
|
+
type ProtocolV2InstallItem = ProtocolV2TargetBinary & {
|
|
105
|
+
kind: ProtocolV2RemoteComponentTarget['kind'];
|
|
106
|
+
};
|
|
107
|
+
type ProtocolV2InstallTarget = ProtocolV2InstallItem & {
|
|
108
|
+
path: string;
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
type ProtocolV2FileTransferParams = PROTO.FirmwareUpload & {
|
|
112
|
+
filePath: string;
|
|
113
|
+
processedSize?: number;
|
|
114
|
+
totalSize?: number;
|
|
115
|
+
onTransferredBytes?: (transferredBytes: number) => void;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
/** RESC bundle okpkg written independently to devicePath through FileWrite. */
|
|
119
|
+
type ProtocolV2ResourceBundleBinary = {
|
|
120
|
+
name: string;
|
|
121
|
+
binary: ArrayBuffer;
|
|
122
|
+
devicePath: string;
|
|
123
|
+
/** Download URL for remote-config mode; omitted in manual mode. */
|
|
124
|
+
url?: string;
|
|
125
|
+
version?: IVersionArray;
|
|
126
|
+
payloadHash?: string;
|
|
127
|
+
headerHash?: string;
|
|
128
|
+
};
|
|
103
129
|
|
|
104
130
|
type ProtocolV2RemoteComponentBinary = ProtocolV2RemoteComponentTarget & {
|
|
105
131
|
binary: ArrayBuffer;
|
|
@@ -108,7 +134,7 @@ type ProtocolV2RemoteComponentBinary = ProtocolV2RemoteComponentTarget & {
|
|
|
108
134
|
type ProtocolV2RemoteComponentTarget = {
|
|
109
135
|
fileName: string;
|
|
110
136
|
targetId: number;
|
|
111
|
-
kind: 'bootloader' | 'firmware'
|
|
137
|
+
kind: 'bootloader' | 'firmware';
|
|
112
138
|
};
|
|
113
139
|
|
|
114
140
|
type ProtocolV2OkppHeader = {
|
|
@@ -161,18 +187,24 @@ const PROTOCOL_V2_REMOTE_COMPONENT_TARGETS: Readonly<
|
|
|
161
187
|
targetId: ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE04,
|
|
162
188
|
kind: 'firmware',
|
|
163
189
|
},
|
|
164
|
-
CRATE: {
|
|
165
|
-
fileName: 'resource.bin',
|
|
166
|
-
targetId: ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_CRATE,
|
|
167
|
-
kind: 'resource',
|
|
168
|
-
},
|
|
169
190
|
};
|
|
170
191
|
|
|
192
|
+
const PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID = new Map<number, FirmwareUpdateV4Target>([
|
|
193
|
+
[ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_BOOTLOADER, 'boot'],
|
|
194
|
+
[ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_APPLICATION_P1, 'app_v1'],
|
|
195
|
+
[ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_APPLICATION_P2, 'app_v2'],
|
|
196
|
+
[ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_COPROCESSOR, 'coprocessor'],
|
|
197
|
+
[ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE01, 'se01'],
|
|
198
|
+
[ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE02, 'se02'],
|
|
199
|
+
[ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE03, 'se03'],
|
|
200
|
+
[ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE04, 'se04'],
|
|
201
|
+
]);
|
|
202
|
+
|
|
171
203
|
const PROTOCOL_V2_ROMLOADER_UNSUPPORTED_MESSAGE =
|
|
172
204
|
'FW_MGMT_TARGET_ROMLOADER is not accepted by the current Pro2 bootloader update request. Flash romloader with the loader-specific flow instead of firmwareUpdateV4.';
|
|
173
205
|
|
|
174
|
-
// hd-transport
|
|
175
|
-
//
|
|
206
|
+
// hd-transport historically decodes scalar enums as enum-name strings.
|
|
207
|
+
// Map them back to firmware protocol values before internal comparisons.
|
|
176
208
|
const PROTOCOL_V2_TARGET_ID_BY_DECODED_NAME = new Map<string, number>(
|
|
177
209
|
Object.entries(ProtocolV2FirmwareTargetType).map(([key, value]) => [key, value])
|
|
178
210
|
);
|
|
@@ -198,25 +230,12 @@ const isProtocolV2ReconnectProbeError = (error: unknown) => {
|
|
|
198
230
|
);
|
|
199
231
|
};
|
|
200
232
|
|
|
201
|
-
const
|
|
202
|
-
const message = getProtocolV2UnknownErrorText(error).toLowerCase();
|
|
203
|
-
return (
|
|
204
|
-
isProtocolV2DeviceDisconnectedError(error) ||
|
|
205
|
-
isProtocolV2ReconnectProbeError(error) ||
|
|
206
|
-
message.includes('libusb_transfer_timed_out') ||
|
|
207
|
-
(message.includes('response timeout') && message.includes('devicefirmwareupdatestatusget')) ||
|
|
208
|
-
message.includes('device not found') ||
|
|
209
|
-
message.includes('transportnotfound')
|
|
210
|
-
);
|
|
211
|
-
};
|
|
212
|
-
|
|
213
|
-
const isProtocolV2StartUpdateTransientError = (error: unknown) => {
|
|
233
|
+
const isProtocolV2FirmwareStatusEndpointUnavailable = (error: unknown) => {
|
|
214
234
|
const message = getProtocolV2UnknownErrorText(error).toLowerCase();
|
|
215
235
|
return (
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
message.includes('
|
|
219
|
-
(message.includes('response timeout') && message.includes('devicefirmwareupdaterequest'))
|
|
236
|
+
message.includes('handler not registered') ||
|
|
237
|
+
message.includes('message handler not found') ||
|
|
238
|
+
message.includes('unsupported message')
|
|
220
239
|
);
|
|
221
240
|
};
|
|
222
241
|
|
|
@@ -262,13 +281,6 @@ const versionArrayToNumber = (version?: IVersionArray) => {
|
|
|
262
281
|
return version[0] * 0x10000 + version[1] * 0x100 + version[2];
|
|
263
282
|
};
|
|
264
283
|
|
|
265
|
-
const versionStringToArray = (version?: string | null): IVersionArray | undefined => {
|
|
266
|
-
if (!version) return undefined;
|
|
267
|
-
const parts = version.split('.').map(part => Number(part));
|
|
268
|
-
if (parts.length !== 3 || parts.some(part => !Number.isFinite(part))) return undefined;
|
|
269
|
-
return parts as IVersionArray;
|
|
270
|
-
};
|
|
271
|
-
|
|
272
284
|
const compareProtocolV2Versions = (current?: IVersionArray, target?: IVersionArray) => {
|
|
273
285
|
const currentNumber = versionArrayToNumber(current);
|
|
274
286
|
const targetNumber = versionArrayToNumber(target);
|
|
@@ -355,6 +367,33 @@ const parseProtocolV2OkppHeader = (bytes: Uint8Array): ProtocolV2OkppHeader | nu
|
|
|
355
367
|
};
|
|
356
368
|
};
|
|
357
369
|
|
|
370
|
+
export const isProtocolV2FirmwareFingerprintValid = (
|
|
371
|
+
binary: ArrayBuffer | Uint8Array,
|
|
372
|
+
fingerprint: string | undefined
|
|
373
|
+
) => {
|
|
374
|
+
const expectedFingerprint = normalizeProtocolV2Hex(fingerprint);
|
|
375
|
+
if (!expectedFingerprint) return true;
|
|
376
|
+
return bytesToHex(sha256(toProtocolV2Bytes(binary))) === expectedFingerprint;
|
|
377
|
+
};
|
|
378
|
+
|
|
379
|
+
export const assertProtocolV2ReconnectIdentity = (
|
|
380
|
+
expectedSerialNumber?: string,
|
|
381
|
+
actualSerialNumber?: string
|
|
382
|
+
) => {
|
|
383
|
+
if (!expectedSerialNumber || !actualSerialNumber) {
|
|
384
|
+
throw ERRORS.TypedError(
|
|
385
|
+
HardwareErrorCode.DeviceNotFound,
|
|
386
|
+
'Protocol V2 reconnect physical identity is unavailable'
|
|
387
|
+
);
|
|
388
|
+
}
|
|
389
|
+
if (actualSerialNumber !== expectedSerialNumber) {
|
|
390
|
+
throw ERRORS.TypedError(
|
|
391
|
+
HardwareErrorCode.DeviceNotFound,
|
|
392
|
+
`Protocol V2 reconnect physical identity mismatch: expected ${expectedSerialNumber}, received ${actualSerialNumber}`
|
|
393
|
+
);
|
|
394
|
+
}
|
|
395
|
+
};
|
|
396
|
+
|
|
358
397
|
/**
|
|
359
398
|
* FirmwareUpdateV4 is the complete Protocol V2 firmware update flow.
|
|
360
399
|
*
|
|
@@ -364,9 +403,16 @@ const parseProtocolV2OkppHeader = (bytes: Uint8Array): ProtocolV2OkppHeader | nu
|
|
|
364
403
|
* - completion waits for target status to finish, reboots to normal, then polls DeviceInfo
|
|
365
404
|
*/
|
|
366
405
|
export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareUpdateV4Params> {
|
|
406
|
+
private protocolV2ExpectedSerialNumber?: string;
|
|
407
|
+
|
|
408
|
+
getSupportedProtocols() {
|
|
409
|
+
return ['V2'] as const;
|
|
410
|
+
}
|
|
411
|
+
|
|
367
412
|
init() {
|
|
368
413
|
this.allowDeviceMode = [UI_REQUEST.BOOTLOADER, UI_REQUEST.NOT_INITIALIZE];
|
|
369
414
|
this.requireDeviceMode = [];
|
|
415
|
+
this.unlockPolicy = 'unlock-before-run';
|
|
370
416
|
this.useDevicePassphraseState = false;
|
|
371
417
|
this.skipForceUpdateCheck = true;
|
|
372
418
|
|
|
@@ -387,7 +433,6 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
387
433
|
|
|
388
434
|
validateParams(payload, [
|
|
389
435
|
{ name: 'chunkSize', type: 'number' },
|
|
390
|
-
{ name: 'resourceBinaries', type: 'array', allowEmpty: true },
|
|
391
436
|
{ name: 'forcedUpdateRes', type: 'boolean' },
|
|
392
437
|
{ name: 'bootloaderBinary', type: 'buffer' },
|
|
393
438
|
{ name: 'romloaderBinary', type: 'buffer' },
|
|
@@ -399,7 +444,9 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
399
444
|
{ name: 'se03Binary', type: 'buffer' },
|
|
400
445
|
{ name: 'se04Binary', type: 'buffer' },
|
|
401
446
|
{ name: 'firmwareType', type: 'string' },
|
|
447
|
+
{ name: 'targetsToUpdate', type: 'array', allowEmpty: true },
|
|
402
448
|
{ name: 'platform', type: 'string' },
|
|
449
|
+
{ name: 'resourceBundleFiles', type: 'array', allowEmpty: true },
|
|
403
450
|
]);
|
|
404
451
|
|
|
405
452
|
this.params = {
|
|
@@ -414,19 +461,24 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
414
461
|
se02Binary: payload.se02Binary,
|
|
415
462
|
se03Binary: payload.se03Binary,
|
|
416
463
|
se04Binary: payload.se04Binary,
|
|
417
|
-
|
|
464
|
+
resourceBundleFiles: payload.resourceBundleFiles,
|
|
418
465
|
firmwareType: payload.firmwareType,
|
|
466
|
+
targetsToUpdate: payload.targetsToUpdate,
|
|
419
467
|
platform: payload.platform,
|
|
420
468
|
};
|
|
421
469
|
}
|
|
422
470
|
|
|
423
|
-
private getProtocolV2FirmwareChunkSize() {
|
|
471
|
+
private getProtocolV2FirmwareChunkSize(direction: 'read' | 'write' = 'write') {
|
|
424
472
|
const payloadChunkSize = Number(this.params?.chunkSize);
|
|
425
473
|
const env = DataManager.getSettings('env');
|
|
426
|
-
const
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
474
|
+
const isBle = this.params?.platform === 'native' || (env && DataManager.isBleConnect(env));
|
|
475
|
+
let maxChunkSize = PROTOCOL_V2_WEBUSB_FILE_CHUNK_SIZE;
|
|
476
|
+
if (isBle) {
|
|
477
|
+
maxChunkSize =
|
|
478
|
+
direction === 'read'
|
|
479
|
+
? PROTOCOL_V2_BLE_FILE_READ_CHUNK_SIZE
|
|
480
|
+
: PROTOCOL_V2_BLE_FILE_CHUNK_SIZE;
|
|
481
|
+
}
|
|
430
482
|
if (!Number.isFinite(payloadChunkSize) || payloadChunkSize <= 0) {
|
|
431
483
|
return maxChunkSize;
|
|
432
484
|
}
|
|
@@ -437,28 +489,22 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
437
489
|
}
|
|
438
490
|
|
|
439
491
|
async run() {
|
|
440
|
-
if (!this.device.isProtocolV2()) {
|
|
441
|
-
throw ERRORS.TypedError(
|
|
442
|
-
HardwareErrorCode.RuntimeError,
|
|
443
|
-
'firmwareUpdateV4 requires a Protocol V2 device'
|
|
444
|
-
);
|
|
445
|
-
}
|
|
446
|
-
|
|
447
492
|
Log.debug('FirmwareUpdateV4 strategy: Protocol V2');
|
|
448
493
|
return this.runProtocolV2();
|
|
449
494
|
}
|
|
450
495
|
|
|
451
496
|
private async runProtocolV2() {
|
|
497
|
+
await this.captureProtocolV2PhysicalIdentity();
|
|
452
498
|
const deviceFeatures = await this.getProtocolV2DeviceFeatures();
|
|
453
499
|
const deviceFirmwareType = getFirmwareType(deviceFeatures);
|
|
454
500
|
const firmwareType = this.params.firmwareType ?? deviceFirmwareType;
|
|
455
501
|
|
|
456
|
-
let resourceBinaryMap: ProtocolV2TargetBinary[] = [];
|
|
457
502
|
let fwBinaryMap: ProtocolV2TargetBinary[] = [];
|
|
458
503
|
let bootloaderBinary: ArrayBuffer | null = null;
|
|
504
|
+
let installItems: ProtocolV2InstallItem[] | undefined;
|
|
505
|
+
let resourceBundles: ProtocolV2ResourceBundleBinary[] | undefined;
|
|
459
506
|
try {
|
|
460
507
|
this.postTipMessage(FirmwareUpdateTipMessage.StartDownloadFirmware);
|
|
461
|
-
resourceBinaryMap = await this.prepareResourceBinaries(firmwareType, deviceFeatures);
|
|
462
508
|
fwBinaryMap = this.collectExplicitTargetBinaries();
|
|
463
509
|
bootloaderBinary = this.prepareBootloaderBinary();
|
|
464
510
|
if (!this.hasExplicitProtocolV2Payload(fwBinaryMap)) {
|
|
@@ -466,16 +512,20 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
466
512
|
firmwareType,
|
|
467
513
|
deviceFeatures
|
|
468
514
|
);
|
|
469
|
-
resourceBinaryMap = remoteBinaries.resourceBinaryMap;
|
|
470
515
|
bootloaderBinary = remoteBinaries.bootloaderBinary;
|
|
471
516
|
fwBinaryMap = remoteBinaries.fwBinaryMap;
|
|
517
|
+
installItems = remoteBinaries.installItems;
|
|
518
|
+
}
|
|
519
|
+
resourceBundles = this.prepareProtocolV2ResourceBundles(firmwareType, deviceFeatures);
|
|
520
|
+
if (resourceBundles?.length) {
|
|
521
|
+
resourceBundles = await this.prefetchProtocolV2ResourceBundles(resourceBundles);
|
|
472
522
|
}
|
|
473
523
|
this.postTipMessage(FirmwareUpdateTipMessage.FinishDownloadFirmware);
|
|
474
524
|
} catch (err) {
|
|
475
525
|
throw ERRORS.TypedError(HardwareErrorCode.FirmwareUpdateDownloadFailed, err.message ?? err);
|
|
476
526
|
}
|
|
477
527
|
|
|
478
|
-
if (
|
|
528
|
+
if (!bootloaderBinary && fwBinaryMap.length === 0 && !resourceBundles?.length) {
|
|
479
529
|
throw ERRORS.TypedError(
|
|
480
530
|
HardwareErrorCode.FirmwareUpdateDownloadFailed,
|
|
481
531
|
'No firmware to update'
|
|
@@ -485,9 +535,10 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
485
535
|
await this.enterProtocolV2BootloaderMode();
|
|
486
536
|
|
|
487
537
|
await this.executeProtocolV2Update({
|
|
488
|
-
resourceBinaryMap,
|
|
489
538
|
fwBinaryMap,
|
|
490
539
|
bootloaderBinary,
|
|
540
|
+
...(installItems ? { installItems } : undefined),
|
|
541
|
+
...(resourceBundles?.length ? { resourceBundles } : undefined),
|
|
491
542
|
});
|
|
492
543
|
|
|
493
544
|
await this.exitProtocolV2BootloaderToNormal();
|
|
@@ -510,41 +561,36 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
510
561
|
throw ERRORS.TypedError(HardwareErrorCode.RuntimeError, 'Device features not available');
|
|
511
562
|
}
|
|
512
563
|
|
|
513
|
-
private
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
throw ERRORS.TypedError(
|
|
518
|
-
HardwareErrorCode.CallMethodInvalidParameter,
|
|
519
|
-
`Parameter [resourceBinaries.${index}] is of type invalid and should be [buffer].`
|
|
520
|
-
);
|
|
521
|
-
}
|
|
522
|
-
});
|
|
564
|
+
private getProtocolV2SerialNumber(deviceInfo: ProtocolV2DeviceInfo) {
|
|
565
|
+
const serialNumber = deviceInfo.hw?.serial_no?.trim();
|
|
566
|
+
return serialNumber || undefined;
|
|
567
|
+
}
|
|
523
568
|
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
569
|
+
private assertProtocolV2DeviceInfoIdentity(deviceInfo: ProtocolV2DeviceInfo) {
|
|
570
|
+
assertProtocolV2ReconnectIdentity(
|
|
571
|
+
this.protocolV2ExpectedSerialNumber,
|
|
572
|
+
this.getProtocolV2SerialNumber(deviceInfo)
|
|
573
|
+
);
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
private async requestProtocolV2PhysicalIdentity() {
|
|
577
|
+
return requestProtocolV2DeviceInfo({
|
|
578
|
+
commands: this.device.getCommands(),
|
|
579
|
+
timeoutMs: PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT,
|
|
534
580
|
});
|
|
581
|
+
}
|
|
535
582
|
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
return [];
|
|
583
|
+
private async captureProtocolV2PhysicalIdentity() {
|
|
584
|
+
const deviceInfo = await this.requestProtocolV2PhysicalIdentity();
|
|
585
|
+
const serialNumber = this.getProtocolV2SerialNumber(deviceInfo);
|
|
586
|
+
assertProtocolV2ReconnectIdentity(serialNumber, serialNumber);
|
|
587
|
+
this.protocolV2ExpectedSerialNumber = serialNumber;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
private async verifyProtocolV2ReconnectIdentity() {
|
|
591
|
+
const deviceInfo = await this.requestProtocolV2PhysicalIdentity();
|
|
592
|
+
this.assertProtocolV2DeviceInfoIdentity(deviceInfo);
|
|
593
|
+
return deviceInfo;
|
|
548
594
|
}
|
|
549
595
|
|
|
550
596
|
private prepareBootloaderBinary(): ArrayBuffer | null {
|
|
@@ -553,12 +599,34 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
553
599
|
|
|
554
600
|
private hasExplicitProtocolV2Payload(fwBinaryMap: ProtocolV2TargetBinary[]) {
|
|
555
601
|
return (
|
|
556
|
-
!!this.params.
|
|
602
|
+
!!this.params.resourceBundleFiles?.length ||
|
|
557
603
|
!!this.params.bootloaderBinary ||
|
|
558
604
|
fwBinaryMap.length > 0
|
|
559
605
|
);
|
|
560
606
|
}
|
|
561
607
|
|
|
608
|
+
private buildProtocolV2InstallItems({
|
|
609
|
+
bootloaderBinary,
|
|
610
|
+
fwBinaryMap,
|
|
611
|
+
}: {
|
|
612
|
+
bootloaderBinary: ArrayBuffer | null;
|
|
613
|
+
fwBinaryMap: ProtocolV2TargetBinary[];
|
|
614
|
+
}): ProtocolV2InstallItem[] {
|
|
615
|
+
const installItems: ProtocolV2InstallItem[] = [];
|
|
616
|
+
|
|
617
|
+
if (bootloaderBinary) {
|
|
618
|
+
installItems.push({
|
|
619
|
+
fileName: 'bootloader.bin',
|
|
620
|
+
binary: bootloaderBinary,
|
|
621
|
+
targetId: ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_BOOTLOADER,
|
|
622
|
+
kind: 'bootloader',
|
|
623
|
+
});
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
installItems.push(...fwBinaryMap.map(item => ({ ...item, kind: 'firmware' as const })));
|
|
627
|
+
return installItems;
|
|
628
|
+
}
|
|
629
|
+
|
|
562
630
|
private getRemoteComponentEntries(release: IFirmwareReleaseInfo) {
|
|
563
631
|
const { components } = release;
|
|
564
632
|
if (!components) return [];
|
|
@@ -594,63 +662,6 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
594
662
|
return target;
|
|
595
663
|
}
|
|
596
664
|
|
|
597
|
-
private getProtocolV2ComponentTargetVersion(
|
|
598
|
-
release: IFirmwareReleaseInfo,
|
|
599
|
-
component: IProtocolV2FirmwareComponent,
|
|
600
|
-
target: ProtocolV2RemoteComponentTarget
|
|
601
|
-
) {
|
|
602
|
-
if (component.version) return component.version;
|
|
603
|
-
if (target.targetId === ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_BOOTLOADER) {
|
|
604
|
-
return release.bootloaderVersion;
|
|
605
|
-
}
|
|
606
|
-
if (
|
|
607
|
-
target.targetId === ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_APPLICATION_P1 ||
|
|
608
|
-
target.targetId === ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_APPLICATION_P2
|
|
609
|
-
) {
|
|
610
|
-
return release.version;
|
|
611
|
-
}
|
|
612
|
-
return undefined;
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
private getProtocolV2ComponentCurrentVersion(
|
|
616
|
-
features: Features,
|
|
617
|
-
target: ProtocolV2RemoteComponentTarget
|
|
618
|
-
) {
|
|
619
|
-
switch (target.targetId) {
|
|
620
|
-
case ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_BOOTLOADER:
|
|
621
|
-
return getDeviceBootloaderVersion(features);
|
|
622
|
-
case ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_APPLICATION_P1:
|
|
623
|
-
case ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_APPLICATION_P2:
|
|
624
|
-
return getDeviceFirmwareVersion(features);
|
|
625
|
-
case ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_COPROCESSOR:
|
|
626
|
-
return getDeviceBLEFirmwareVersion(features);
|
|
627
|
-
case ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE01:
|
|
628
|
-
return versionStringToArray(features.se01Version);
|
|
629
|
-
case ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE02:
|
|
630
|
-
return versionStringToArray(features.se02Version);
|
|
631
|
-
case ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE03:
|
|
632
|
-
return versionStringToArray(features.se03Version);
|
|
633
|
-
case ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE04:
|
|
634
|
-
return versionStringToArray(features.se04Version);
|
|
635
|
-
default:
|
|
636
|
-
return undefined;
|
|
637
|
-
}
|
|
638
|
-
}
|
|
639
|
-
|
|
640
|
-
private isProtocolV2ComponentVersionSatisfied(
|
|
641
|
-
release: IFirmwareReleaseInfo,
|
|
642
|
-
component: IProtocolV2FirmwareComponent,
|
|
643
|
-
target: ProtocolV2RemoteComponentTarget,
|
|
644
|
-
features: Features
|
|
645
|
-
) {
|
|
646
|
-
const targetVersion = this.getProtocolV2ComponentTargetVersion(release, component, target);
|
|
647
|
-
if (!targetVersion) return false;
|
|
648
|
-
|
|
649
|
-
const currentVersion = this.getProtocolV2ComponentCurrentVersion(features, target);
|
|
650
|
-
const compareResult = compareProtocolV2Versions(currentVersion, targetVersion);
|
|
651
|
-
return compareResult !== undefined && compareResult >= 0;
|
|
652
|
-
}
|
|
653
|
-
|
|
654
665
|
private getProtocolV2ResourceFilePath(path: string) {
|
|
655
666
|
if (path.startsWith('vol')) return path;
|
|
656
667
|
if (path.startsWith('/')) return `vol0:${path}`;
|
|
@@ -673,7 +684,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
673
684
|
return null;
|
|
674
685
|
}
|
|
675
686
|
|
|
676
|
-
const chunkSize = this.getProtocolV2FirmwareChunkSize();
|
|
687
|
+
const chunkSize = this.getProtocolV2FirmwareChunkSize('read');
|
|
677
688
|
const chunks: Uint8Array[] = [];
|
|
678
689
|
let offset = 0;
|
|
679
690
|
while (offset < PROTOCOL_V2_OKPP_HEADER_SIZE) {
|
|
@@ -702,95 +713,6 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
702
713
|
return parseProtocolV2OkppHeader(headerBytes);
|
|
703
714
|
}
|
|
704
715
|
|
|
705
|
-
private async isProtocolV2ResourcePackageMatched(
|
|
706
|
-
pkg: IProtocolV2ResourceManifestPackage,
|
|
707
|
-
manifestVersion?: IVersionArray
|
|
708
|
-
) {
|
|
709
|
-
try {
|
|
710
|
-
const header = await this.readProtocolV2DeviceFileHeader(pkg.path);
|
|
711
|
-
if (!header) return false;
|
|
712
|
-
|
|
713
|
-
const expectedType = pkg.type ?? 'RESC';
|
|
714
|
-
const expectedVersion = pkg.version ?? manifestVersion;
|
|
715
|
-
if (header.type !== expectedType) return false;
|
|
716
|
-
if (expectedVersion && compareProtocolV2Versions(header.version, expectedVersion) !== 0) {
|
|
717
|
-
return false;
|
|
718
|
-
}
|
|
719
|
-
|
|
720
|
-
const expectedPayloadHash = normalizeProtocolV2Hex(pkg.payloadHash);
|
|
721
|
-
if (expectedPayloadHash && header.payloadHash !== expectedPayloadHash) return false;
|
|
722
|
-
|
|
723
|
-
const expectedHeaderHash = normalizeProtocolV2Hex(pkg.headerHash);
|
|
724
|
-
if (expectedHeaderHash && header.headerHash !== expectedHeaderHash) return false;
|
|
725
|
-
|
|
726
|
-
return true;
|
|
727
|
-
} catch (error) {
|
|
728
|
-
Log.log(`Protocol V2 resource package check failed for ${pkg.path}: `, error);
|
|
729
|
-
return false;
|
|
730
|
-
}
|
|
731
|
-
}
|
|
732
|
-
|
|
733
|
-
private async isProtocolV2ResourceManifestSatisfied(
|
|
734
|
-
manifest: IFirmwareReleaseInfo['resourceManifest']
|
|
735
|
-
) {
|
|
736
|
-
if (!manifest?.packages?.length) return false;
|
|
737
|
-
|
|
738
|
-
for (const pkg of manifest.packages) {
|
|
739
|
-
if (!(await this.isProtocolV2ResourcePackageMatched(pkg, manifest.version))) {
|
|
740
|
-
return false;
|
|
741
|
-
}
|
|
742
|
-
}
|
|
743
|
-
return true;
|
|
744
|
-
}
|
|
745
|
-
|
|
746
|
-
private getProtocolV2ResourceManifest(
|
|
747
|
-
release: IFirmwareReleaseInfo,
|
|
748
|
-
component: IProtocolV2FirmwareComponent
|
|
749
|
-
) {
|
|
750
|
-
return component.resourceManifest ?? release.resourceManifest;
|
|
751
|
-
}
|
|
752
|
-
|
|
753
|
-
private getProtocolV2ResourceComponentFileName(key: string) {
|
|
754
|
-
const safeKey = key.replace(/[^a-z0-9_-]/gi, '_') || 'resource';
|
|
755
|
-
return `resource-${safeKey}.bin`;
|
|
756
|
-
}
|
|
757
|
-
|
|
758
|
-
private async shouldInstallRemoteProtocolV2Component(
|
|
759
|
-
release: IFirmwareReleaseInfo,
|
|
760
|
-
key: string,
|
|
761
|
-
component: IProtocolV2FirmwareComponent,
|
|
762
|
-
target: ProtocolV2RemoteComponentTarget,
|
|
763
|
-
features: Features
|
|
764
|
-
) {
|
|
765
|
-
if (target.kind === 'resource') {
|
|
766
|
-
if (
|
|
767
|
-
this.params.forcedUpdateRes ||
|
|
768
|
-
features.bootloaderMode ||
|
|
769
|
-
features.mode === 'bootloader'
|
|
770
|
-
) {
|
|
771
|
-
return true;
|
|
772
|
-
}
|
|
773
|
-
const resourceMatched = await this.isProtocolV2ResourceManifestSatisfied(
|
|
774
|
-
this.getProtocolV2ResourceManifest(release, component)
|
|
775
|
-
);
|
|
776
|
-
if (resourceMatched) {
|
|
777
|
-
Log.log(`[FirmwareUpdateV4] skip Protocol V2 resource component ${key}; manifest matched`);
|
|
778
|
-
}
|
|
779
|
-
return !resourceMatched;
|
|
780
|
-
}
|
|
781
|
-
|
|
782
|
-
const versionSatisfied = this.isProtocolV2ComponentVersionSatisfied(
|
|
783
|
-
release,
|
|
784
|
-
component,
|
|
785
|
-
target,
|
|
786
|
-
features
|
|
787
|
-
);
|
|
788
|
-
if (versionSatisfied) {
|
|
789
|
-
Log.log(`[FirmwareUpdateV4] skip Protocol V2 component ${key}; version is up to date`);
|
|
790
|
-
}
|
|
791
|
-
return !versionSatisfied;
|
|
792
|
-
}
|
|
793
|
-
|
|
794
716
|
private async downloadRemoteProtocolV2Component(
|
|
795
717
|
key: string,
|
|
796
718
|
component: IProtocolV2FirmwareComponent
|
|
@@ -804,6 +726,22 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
804
726
|
}
|
|
805
727
|
|
|
806
728
|
const { binary } = await getSysResourceBinary(component.url);
|
|
729
|
+
if (!isProtocolV2FirmwareFingerprintValid(binary, component.fingerprint)) {
|
|
730
|
+
throw ERRORS.TypedError(
|
|
731
|
+
HardwareErrorCode.RuntimeError,
|
|
732
|
+
`Protocol V2 firmware fingerprint mismatch: ${key}/${component.target}`
|
|
733
|
+
);
|
|
734
|
+
}
|
|
735
|
+
const expectedPayloadHash = normalizeProtocolV2Hex(component.payloadHash);
|
|
736
|
+
if (expectedPayloadHash) {
|
|
737
|
+
const header = parseProtocolV2OkppHeader(toProtocolV2Bytes(binary));
|
|
738
|
+
if (!header || header.payloadHash !== expectedPayloadHash) {
|
|
739
|
+
throw ERRORS.TypedError(
|
|
740
|
+
HardwareErrorCode.RuntimeError,
|
|
741
|
+
`Protocol V2 firmware payload hash mismatch: ${key}/${component.target}`
|
|
742
|
+
);
|
|
743
|
+
}
|
|
744
|
+
}
|
|
807
745
|
return {
|
|
808
746
|
...target,
|
|
809
747
|
binary,
|
|
@@ -813,66 +751,274 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
813
751
|
private async prepareRemoteProtocolV2Binaries(firmwareType: EFirmwareType, features: Features) {
|
|
814
752
|
const release = DataManager.getFirmwareLatestRelease(features, firmwareType);
|
|
815
753
|
|
|
816
|
-
const resourceBinaryMap: ProtocolV2TargetBinary[] = [];
|
|
817
754
|
let bootloaderBinary: ArrayBuffer | null = null;
|
|
818
755
|
const fwBinaryMap: ProtocolV2TargetBinary[] = [];
|
|
756
|
+
const installItems: ProtocolV2InstallItem[] = [];
|
|
819
757
|
|
|
820
758
|
if (!release) {
|
|
821
759
|
return {
|
|
822
|
-
resourceBinaryMap,
|
|
823
760
|
bootloaderBinary,
|
|
824
761
|
fwBinaryMap,
|
|
762
|
+
installItems,
|
|
825
763
|
};
|
|
826
764
|
}
|
|
827
765
|
|
|
828
766
|
const entries = this.getRemoteComponentEntries(release);
|
|
767
|
+
const targetsToUpdate = new Set(this.params.targetsToUpdate ?? []);
|
|
829
768
|
|
|
830
769
|
for (const [key, component] of entries) {
|
|
831
|
-
const
|
|
832
|
-
const
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
features
|
|
838
|
-
);
|
|
839
|
-
if (shouldInstall) {
|
|
770
|
+
const targetName = component.target?.toUpperCase();
|
|
771
|
+
const target = PROTOCOL_V2_REMOTE_COMPONENT_TARGETS[targetName];
|
|
772
|
+
const updateTarget = target
|
|
773
|
+
? PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID.get(target.targetId)
|
|
774
|
+
: undefined;
|
|
775
|
+
if (updateTarget && targetsToUpdate.has(updateTarget)) {
|
|
840
776
|
const remoteBinary = await this.downloadRemoteProtocolV2Component(key, component);
|
|
841
|
-
if (remoteBinary.kind === '
|
|
842
|
-
|
|
843
|
-
|
|
777
|
+
if (remoteBinary.kind === 'bootloader') {
|
|
778
|
+
bootloaderBinary = remoteBinary.binary;
|
|
779
|
+
installItems.push({
|
|
780
|
+
fileName: remoteBinary.fileName,
|
|
844
781
|
binary: remoteBinary.binary,
|
|
845
782
|
targetId: remoteBinary.targetId,
|
|
783
|
+
kind: remoteBinary.kind,
|
|
846
784
|
});
|
|
847
|
-
} else if (remoteBinary.kind === 'bootloader') {
|
|
848
|
-
bootloaderBinary = remoteBinary.binary;
|
|
849
785
|
} else {
|
|
850
|
-
|
|
786
|
+
const binaryEntry = {
|
|
851
787
|
fileName: remoteBinary.fileName,
|
|
852
788
|
binary: remoteBinary.binary,
|
|
853
789
|
targetId: remoteBinary.targetId,
|
|
854
|
-
}
|
|
790
|
+
};
|
|
791
|
+
fwBinaryMap.push(binaryEntry);
|
|
792
|
+
installItems.push({ ...binaryEntry, kind: remoteBinary.kind });
|
|
855
793
|
}
|
|
856
794
|
}
|
|
857
795
|
}
|
|
858
796
|
|
|
859
797
|
return {
|
|
860
|
-
resourceBinaryMap,
|
|
861
798
|
bootloaderBinary,
|
|
862
799
|
fwBinaryMap,
|
|
800
|
+
installItems,
|
|
863
801
|
};
|
|
864
802
|
}
|
|
865
803
|
|
|
804
|
+
// ============================================================
|
|
805
|
+
// Incremental RESC bundle sync through FileRead and FilesystemFileWrite
|
|
806
|
+
// ============================================================
|
|
807
|
+
|
|
808
|
+
/**
|
|
809
|
+
* Prepare the RESC bundle list.
|
|
810
|
+
*
|
|
811
|
+
* Two modes, matching FirmwareUpdateV3 binary-versus-version behavior:
|
|
812
|
+
* - resourceBundleFiles supplied: use binaries directly without version checks.
|
|
813
|
+
* - Otherwise load release.resourceBundles from remote config.json; the binaries
|
|
814
|
+
* are prefetched before reboot and synchronization skips matching device headers.
|
|
815
|
+
*/
|
|
816
|
+
private prepareProtocolV2ResourceBundles(
|
|
817
|
+
firmwareType: EFirmwareType,
|
|
818
|
+
features: Features
|
|
819
|
+
): ProtocolV2ResourceBundleBinary[] | undefined {
|
|
820
|
+
// Manual binaries are installed directly without comparison.
|
|
821
|
+
if (this.params.resourceBundleFiles?.length) {
|
|
822
|
+
return this.params.resourceBundleFiles.map((file, index) => {
|
|
823
|
+
const devicePath = validateProtocolV2FilesystemPath(
|
|
824
|
+
file.devicePath,
|
|
825
|
+
`resourceBundleFiles[${index}].devicePath`
|
|
826
|
+
);
|
|
827
|
+
return {
|
|
828
|
+
name: devicePath.split('/').pop() ?? devicePath,
|
|
829
|
+
binary: file.binary,
|
|
830
|
+
devicePath,
|
|
831
|
+
};
|
|
832
|
+
});
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
if (!this.params.targetsToUpdate?.includes('resource')) {
|
|
836
|
+
return undefined;
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
// Remote-config bundles are downloaded and compared later.
|
|
840
|
+
const release = DataManager.getFirmwareLatestRelease(features, firmwareType);
|
|
841
|
+
if (!release?.resourceBundles?.length) return undefined;
|
|
842
|
+
|
|
843
|
+
return release.resourceBundles.map((bundle, index) => ({
|
|
844
|
+
name: bundle.name,
|
|
845
|
+
binary: new ArrayBuffer(0),
|
|
846
|
+
devicePath: validateProtocolV2FilesystemPath(
|
|
847
|
+
bundle.devicePath,
|
|
848
|
+
`resourceBundles[${index}].devicePath`
|
|
849
|
+
),
|
|
850
|
+
url: bundle.url,
|
|
851
|
+
version: bundle.version,
|
|
852
|
+
payloadHash: bundle.payloadHash,
|
|
853
|
+
headerHash: bundle.headerHash,
|
|
854
|
+
})) as ProtocolV2ResourceBundleBinary[];
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
private async prefetchProtocolV2ResourceBundles(
|
|
858
|
+
bundles: ProtocolV2ResourceBundleBinary[]
|
|
859
|
+
): Promise<ProtocolV2ResourceBundleBinary[]> {
|
|
860
|
+
const prefetched: ProtocolV2ResourceBundleBinary[] = [];
|
|
861
|
+
for (const bundle of bundles) {
|
|
862
|
+
let { binary } = bundle;
|
|
863
|
+
let downloadedFromRemote = false;
|
|
864
|
+
if (binary.byteLength === 0) {
|
|
865
|
+
if (!bundle.url) {
|
|
866
|
+
throw new Error(`Missing Protocol V2 RESC bundle binary: ${bundle.name}`);
|
|
867
|
+
}
|
|
868
|
+
Log.log(`[FirmwareUpdateV4] downloading remote RESC bundle ${bundle.name}`);
|
|
869
|
+
({ binary } = await getSysResourceBinary(bundle.url));
|
|
870
|
+
downloadedFromRemote = true;
|
|
871
|
+
}
|
|
872
|
+
if (binary.byteLength === 0) {
|
|
873
|
+
throw new Error(`Protocol V2 RESC bundle is empty: ${bundle.name}`);
|
|
874
|
+
}
|
|
875
|
+
if (downloadedFromRemote) {
|
|
876
|
+
const header = parseProtocolV2OkppHeader(toProtocolV2Bytes(binary));
|
|
877
|
+
if (!header || header.type !== 'RESC') {
|
|
878
|
+
throw new Error(`Invalid Protocol V2 RESC bundle header: ${bundle.name}`);
|
|
879
|
+
}
|
|
880
|
+
if (bundle.version && compareProtocolV2Versions(header.version, bundle.version) !== 0) {
|
|
881
|
+
throw new Error(`Protocol V2 RESC bundle version mismatch: ${bundle.name}`);
|
|
882
|
+
}
|
|
883
|
+
const expectedPayloadHash = normalizeProtocolV2Hex(bundle.payloadHash);
|
|
884
|
+
if (expectedPayloadHash && header.payloadHash !== expectedPayloadHash) {
|
|
885
|
+
throw new Error(`Protocol V2 RESC bundle payload hash mismatch: ${bundle.name}`);
|
|
886
|
+
}
|
|
887
|
+
const expectedHeaderHash = normalizeProtocolV2Hex(bundle.headerHash);
|
|
888
|
+
if (expectedHeaderHash && header.headerHash !== expectedHeaderHash) {
|
|
889
|
+
throw new Error(`Protocol V2 RESC bundle header hash mismatch: ${bundle.name}`);
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
prefetched.push({ ...bundle, binary });
|
|
893
|
+
}
|
|
894
|
+
return prefetched;
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
/**
|
|
898
|
+
* Synchronize RESC bundles to the device.
|
|
899
|
+
*
|
|
900
|
+
* Manual mode writes supplied binaries directly.
|
|
901
|
+
* Remote-config mode uses prefetched binaries and skips matching bundles after FileRead.
|
|
902
|
+
*/
|
|
903
|
+
private async syncProtocolV2ResourceBundles(
|
|
904
|
+
bundles: ProtocolV2ResourceBundleBinary[],
|
|
905
|
+
firmwareSize: number
|
|
906
|
+
): Promise<{ processedSize: number; totalSize: number }> {
|
|
907
|
+
const transferStartTime = Date.now();
|
|
908
|
+
const transferTransport = this.getProtocolV2FirmwareTransferTransport();
|
|
909
|
+
|
|
910
|
+
const isRemoteMode = bundles.some(bundle => !!bundle.url);
|
|
911
|
+
let bundlesToSync = bundles;
|
|
912
|
+
|
|
913
|
+
// Remote binaries were prefetched before bootloader entry. Only device-local
|
|
914
|
+
// header comparison and transfer are allowed in this phase.
|
|
915
|
+
if (isRemoteMode) {
|
|
916
|
+
const filtered: ProtocolV2ResourceBundleBinary[] = [];
|
|
917
|
+
for (const bundle of bundles) {
|
|
918
|
+
// Compare the existing device header.
|
|
919
|
+
const upToDate = await this.isProtocolV2ResourceBundleUpToDate(bundle);
|
|
920
|
+
if (upToDate) {
|
|
921
|
+
Log.log(`[FirmwareUpdateV4] skip RESC bundle ${bundle.name}; already up to date`);
|
|
922
|
+
} else {
|
|
923
|
+
filtered.push(bundle);
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
bundlesToSync = filtered;
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
if (bundlesToSync.length === 0) {
|
|
930
|
+
Log.log('[FirmwareUpdateV4] all RESC bundles up to date, nothing to sync');
|
|
931
|
+
return { processedSize: 0, totalSize: firmwareSize };
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
// Write directly to the device through FileWrite.
|
|
935
|
+
let totalSize = 0;
|
|
936
|
+
for (const b of bundlesToSync) totalSize += b.binary.byteLength;
|
|
937
|
+
|
|
938
|
+
const transferTotalSize = totalSize + firmwareSize;
|
|
939
|
+
let processedSize = 0;
|
|
940
|
+
for (const bundle of bundlesToSync) {
|
|
941
|
+
Log.log(
|
|
942
|
+
`[FirmwareUpdateV4] syncing RESC bundle ${bundle.name} -> ${bundle.devicePath} bytes=${bundle.binary.byteLength}`
|
|
943
|
+
);
|
|
944
|
+
processedSize = await this.protocolV2CommonUpdateProcess({
|
|
945
|
+
payload: bundle.binary,
|
|
946
|
+
filePath: bundle.devicePath,
|
|
947
|
+
processedSize,
|
|
948
|
+
totalSize: transferTotalSize,
|
|
949
|
+
});
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
const elapsedMs = Date.now() - transferStartTime;
|
|
953
|
+
Log.log(
|
|
954
|
+
`[FirmwareUpdateV4] RESC bundle sync finished transport=${transferTransport} bytes=${totalSize} elapsed=${(
|
|
955
|
+
elapsedMs / 1000
|
|
956
|
+
).toFixed(2)}s speed=${formatProtocolV2TransferSpeed(totalSize, elapsedMs)} KB/s`
|
|
957
|
+
);
|
|
958
|
+
return { processedSize, totalSize: transferTotalSize };
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
/**
|
|
962
|
+
* Compare the existing okpkg OKPP header in remote-config mode.
|
|
963
|
+
*/
|
|
964
|
+
private async isProtocolV2ResourceBundleUpToDate(
|
|
965
|
+
bundle: ProtocolV2ResourceBundleBinary
|
|
966
|
+
): Promise<boolean> {
|
|
967
|
+
if (this.params.forcedUpdateRes) return false;
|
|
968
|
+
if (!bundle.version && !bundle.payloadHash) return false;
|
|
969
|
+
|
|
970
|
+
try {
|
|
971
|
+
const header = await this.readProtocolV2DeviceFileHeader(bundle.devicePath);
|
|
972
|
+
if (!header) return false;
|
|
973
|
+
|
|
974
|
+
if (bundle.version) {
|
|
975
|
+
const cmp = compareProtocolV2Versions(header.version, bundle.version);
|
|
976
|
+
if (cmp === undefined || cmp !== 0) return false;
|
|
977
|
+
}
|
|
978
|
+
if (bundle.payloadHash) {
|
|
979
|
+
const expected = normalizeProtocolV2Hex(bundle.payloadHash);
|
|
980
|
+
if (expected && header.payloadHash !== expected) return false;
|
|
981
|
+
}
|
|
982
|
+
if (bundle.headerHash) {
|
|
983
|
+
const expected = normalizeProtocolV2Hex(bundle.headerHash);
|
|
984
|
+
if (expected && header.headerHash !== expected) return false;
|
|
985
|
+
}
|
|
986
|
+
return true;
|
|
987
|
+
} catch (error) {
|
|
988
|
+
Log.log(`[FirmwareUpdateV4] RESC bundle ${bundle.name} header check failed: `, error);
|
|
989
|
+
return false;
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
|
|
866
993
|
private isProtocolV2BootloaderMode() {
|
|
867
994
|
if (typeof this.device.isBootloader === 'function') {
|
|
868
995
|
return this.device.isBootloader();
|
|
869
996
|
}
|
|
870
|
-
return
|
|
997
|
+
return (
|
|
998
|
+
this.device.features?.mode === 'bootloader' ||
|
|
999
|
+
(this.device.features?.mode == null && !!this.device.features?.bootloaderMode)
|
|
1000
|
+
);
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
private isProtocolV2RomloaderMode() {
|
|
1004
|
+
if (!this.device.isProtocolV2() || this.device.getCurrentDeviceType() !== EDeviceType.Pro2) {
|
|
1005
|
+
return false;
|
|
1006
|
+
}
|
|
1007
|
+
if (typeof this.device.isRomloader === 'function') {
|
|
1008
|
+
return this.device.isRomloader();
|
|
1009
|
+
}
|
|
1010
|
+
return this.device.features?.mode === 'romloader';
|
|
871
1011
|
}
|
|
872
1012
|
|
|
873
1013
|
async enterProtocolV2BootloaderMode() {
|
|
1014
|
+
// romloader is the first update environment and forwards targets to bootloader.
|
|
1015
|
+
// It rejects DeviceRebootType.Bootloader, so reuse the current connection.
|
|
1016
|
+
if (this.isProtocolV2RomloaderMode()) {
|
|
1017
|
+
Log.debug('Protocol V2 device is in romloader mode; start firmware update directly');
|
|
1018
|
+
return false;
|
|
1019
|
+
}
|
|
874
1020
|
if (this.isProtocolV2BootloaderMode()) {
|
|
875
|
-
Log.debug('Protocol V2 device is already in bootloader mode, skip reboot
|
|
1021
|
+
Log.debug('Protocol V2 device is already in bootloader mode, skip reboot');
|
|
876
1022
|
return false;
|
|
877
1023
|
}
|
|
878
1024
|
|
|
@@ -906,12 +1052,19 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
906
1052
|
commands: this.device.getCommands(),
|
|
907
1053
|
timeoutMs: PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT,
|
|
908
1054
|
});
|
|
909
|
-
|
|
910
|
-
|
|
1055
|
+
this.assertProtocolV2DeviceInfoIdentity(deviceInfo);
|
|
1056
|
+
const features = await this.device.probeProtocolV2RuntimeState(
|
|
1057
|
+
deviceInfo,
|
|
1058
|
+
PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT
|
|
1059
|
+
);
|
|
1060
|
+
if (features?.mode === 'bootloader') {
|
|
911
1061
|
return features;
|
|
912
1062
|
}
|
|
913
1063
|
lastError = new Error('Protocol V2 device is reachable but is not in bootloader mode');
|
|
914
1064
|
} catch (error) {
|
|
1065
|
+
if (this.isProtocolV2ReconnectIdentityError(error)) {
|
|
1066
|
+
throw error;
|
|
1067
|
+
}
|
|
915
1068
|
lastError = error;
|
|
916
1069
|
Log.log('Protocol V2 bootloader mode not ready, polling reconnect: ', error);
|
|
917
1070
|
}
|
|
@@ -927,8 +1080,8 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
927
1080
|
}
|
|
928
1081
|
|
|
929
1082
|
/**
|
|
930
|
-
*
|
|
931
|
-
*
|
|
1083
|
+
* Collect explicit target binaries grouped by DeviceFirmwareTargetType.
|
|
1084
|
+
* Filenames are display-only staging paths because target_id is explicit.
|
|
932
1085
|
*/
|
|
933
1086
|
private collectExplicitTargetBinaries() {
|
|
934
1087
|
const entries: ProtocolV2TargetBinary[] = [];
|
|
@@ -965,23 +1118,48 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
965
1118
|
}
|
|
966
1119
|
|
|
967
1120
|
private async executeProtocolV2Update({
|
|
968
|
-
resourceBinaryMap,
|
|
969
1121
|
fwBinaryMap,
|
|
970
1122
|
bootloaderBinary,
|
|
1123
|
+
installItems,
|
|
1124
|
+
resourceBundles,
|
|
971
1125
|
}: {
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
1126
|
+
fwBinaryMap?: ProtocolV2TargetBinary[];
|
|
1127
|
+
bootloaderBinary?: ArrayBuffer | null;
|
|
1128
|
+
installItems?: ProtocolV2InstallItem[];
|
|
1129
|
+
resourceBundles?: ProtocolV2ResourceBundleBinary[];
|
|
975
1130
|
}) {
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
1131
|
+
const orderedInstallItems =
|
|
1132
|
+
installItems ??
|
|
1133
|
+
this.buildProtocolV2InstallItems({
|
|
1134
|
+
bootloaderBinary: bootloaderBinary ?? null,
|
|
1135
|
+
fwBinaryMap: fwBinaryMap ?? [],
|
|
1136
|
+
});
|
|
979
1137
|
|
|
980
|
-
|
|
981
|
-
for (const
|
|
982
|
-
if (bootloaderBinary) totalSize += bootloaderBinary.byteLength;
|
|
1138
|
+
let firmwareSize = 0;
|
|
1139
|
+
for (const item of orderedInstallItems) firmwareSize += item.binary.byteLength;
|
|
983
1140
|
|
|
984
1141
|
this.postTipMessage(FirmwareUpdateTipMessage.StartTransferData);
|
|
1142
|
+
|
|
1143
|
+
let processedSize = 0;
|
|
1144
|
+
let totalSize = firmwareSize;
|
|
1145
|
+
if (resourceBundles?.length) {
|
|
1146
|
+
const resourceTransfer = await this.syncProtocolV2ResourceBundles(
|
|
1147
|
+
resourceBundles,
|
|
1148
|
+
firmwareSize
|
|
1149
|
+
);
|
|
1150
|
+
processedSize = resourceTransfer.processedSize;
|
|
1151
|
+
totalSize = resourceTransfer.totalSize;
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
// Skip staging and installation when the update contains RESC bundles only.
|
|
1155
|
+
if (orderedInstallItems.length === 0) {
|
|
1156
|
+
Log.log('[FirmwareUpdateV4] no firmware targets to install (RESC bundles only)');
|
|
1157
|
+
if (totalSize > 0) {
|
|
1158
|
+
this.postProgressMessage(100, 'transferData');
|
|
1159
|
+
}
|
|
1160
|
+
return;
|
|
1161
|
+
}
|
|
1162
|
+
let transferredSize = processedSize;
|
|
985
1163
|
const transferStartTime = Date.now();
|
|
986
1164
|
const transferTransport = this.getProtocolV2FirmwareTransferTransport();
|
|
987
1165
|
const chunkSize = this.getProtocolV2FirmwareChunkSize();
|
|
@@ -992,64 +1170,27 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
992
1170
|
`[FirmwareUpdateV4] transfer started transport=${transferTransport} total=${totalSize} bytes chunk=${chunkSize} bytes`
|
|
993
1171
|
);
|
|
994
1172
|
|
|
995
|
-
const
|
|
996
|
-
const targets: Array<{ target_id: number; path: string }> = [];
|
|
1173
|
+
const stagedInstallTargets: ProtocolV2InstallTarget[] = [];
|
|
997
1174
|
|
|
998
1175
|
try {
|
|
999
|
-
for (const
|
|
1000
|
-
const
|
|
1001
|
-
Log.log(
|
|
1002
|
-
`[FirmwareUpdateV4] staging resource via FilesystemFileWrite target=${resource.targetId} path=${resourceFilePath} bytes=${resource.binary.byteLength}`
|
|
1003
|
-
);
|
|
1004
|
-
processedSize = await this.protocolV2CommonUpdateProcess({
|
|
1005
|
-
payload: resource.binary,
|
|
1006
|
-
filePath: resourceFilePath,
|
|
1007
|
-
processedSize,
|
|
1008
|
-
totalSize,
|
|
1009
|
-
onTransferredBytes,
|
|
1010
|
-
});
|
|
1011
|
-
transferredSize = processedSize;
|
|
1012
|
-
resourceTargets.push({
|
|
1013
|
-
target_id: resource.targetId,
|
|
1014
|
-
path: resourceFilePath,
|
|
1015
|
-
});
|
|
1016
|
-
}
|
|
1017
|
-
|
|
1018
|
-
if (bootloaderBinary) {
|
|
1019
|
-
const bootloaderPath = `${PROTOCOL_V2_FIRMWARE_STAGING_VOLUME}bootloader.bin`;
|
|
1176
|
+
for (const item of orderedInstallItems) {
|
|
1177
|
+
const filePath = this.getProtocolV2InstallItemStagingPath(item);
|
|
1020
1178
|
Log.log(
|
|
1021
|
-
`[FirmwareUpdateV4] staging
|
|
1179
|
+
`[FirmwareUpdateV4] staging ${item.kind} via FilesystemFileWrite target=${item.targetId} path=${filePath} source=${item.fileName} bytes=${item.binary.byteLength}`
|
|
1022
1180
|
);
|
|
1023
1181
|
processedSize = await this.protocolV2CommonUpdateProcess({
|
|
1024
|
-
payload:
|
|
1025
|
-
filePath
|
|
1182
|
+
payload: item.binary,
|
|
1183
|
+
filePath,
|
|
1026
1184
|
processedSize,
|
|
1027
1185
|
totalSize,
|
|
1028
1186
|
onTransferredBytes,
|
|
1029
1187
|
});
|
|
1030
1188
|
transferredSize = processedSize;
|
|
1031
|
-
|
|
1032
|
-
target_id: ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_BOOTLOADER,
|
|
1033
|
-
path: bootloaderPath,
|
|
1034
|
-
});
|
|
1035
|
-
}
|
|
1189
|
+
await this.verifyProtocolV2StagedFile(filePath, item.binary.byteLength);
|
|
1036
1190
|
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
`[FirmwareUpdateV4] staging firmware via FilesystemFileWrite target=${fwbinary.targetId} path=${firmwarePath} bytes=${fwbinary.binary.byteLength}`
|
|
1041
|
-
);
|
|
1042
|
-
processedSize = await this.protocolV2CommonUpdateProcess({
|
|
1043
|
-
payload: fwbinary.binary,
|
|
1044
|
-
filePath: firmwarePath,
|
|
1045
|
-
processedSize,
|
|
1046
|
-
totalSize,
|
|
1047
|
-
onTransferredBytes,
|
|
1048
|
-
});
|
|
1049
|
-
transferredSize = processedSize;
|
|
1050
|
-
targets.push({
|
|
1051
|
-
target_id: fwbinary.targetId,
|
|
1052
|
-
path: firmwarePath,
|
|
1191
|
+
stagedInstallTargets.push({
|
|
1192
|
+
...item,
|
|
1193
|
+
path: filePath,
|
|
1053
1194
|
});
|
|
1054
1195
|
}
|
|
1055
1196
|
|
|
@@ -1074,155 +1215,166 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1074
1215
|
}
|
|
1075
1216
|
|
|
1076
1217
|
this.postTipMessage(FirmwareUpdateTipMessage.ConfirmOnDevice);
|
|
1077
|
-
for (const resourceTarget of resourceTargets) {
|
|
1078
|
-
const resourceTargetsBatch = [resourceTarget];
|
|
1079
|
-
Log.log(
|
|
1080
|
-
`[FirmwareUpdateV4] DeviceFirmwareUpdateRequest resources=${JSON.stringify(
|
|
1081
|
-
resourceTargetsBatch
|
|
1082
|
-
)}`
|
|
1083
|
-
);
|
|
1084
|
-
const startResponse = await this.protocolV2StartFirmwareUpdate({
|
|
1085
|
-
targets: resourceTargetsBatch,
|
|
1086
|
-
});
|
|
1087
|
-
await this.waitForProtocolV2FirmwareUpdateComplete(resourceTargetsBatch, startResponse);
|
|
1088
|
-
}
|
|
1089
|
-
if (targets.length > 0) {
|
|
1090
|
-
Log.log(`[FirmwareUpdateV4] DeviceFirmwareUpdateRequest targets=${JSON.stringify(targets)}`);
|
|
1091
|
-
const startResponse = await this.protocolV2StartFirmwareUpdate({ targets });
|
|
1092
|
-
await this.waitForProtocolV2FirmwareUpdateComplete(targets, startResponse);
|
|
1093
|
-
}
|
|
1094
|
-
}
|
|
1095
|
-
|
|
1096
|
-
private async queryProtocolV2FirmwareUpdateStatus() {
|
|
1097
|
-
const typedCall = this.device.getCommands().typedCall.bind(this.device.getCommands());
|
|
1098
|
-
return typedCall(
|
|
1099
|
-
'DeviceFirmwareUpdateStatusGet',
|
|
1100
|
-
'DeviceFirmwareUpdateStatus',
|
|
1101
|
-
{},
|
|
1102
|
-
{
|
|
1103
|
-
timeoutMs: PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT,
|
|
1104
|
-
}
|
|
1105
|
-
);
|
|
1106
|
-
}
|
|
1107
1218
|
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
timeoutMs: PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT,
|
|
1116
|
-
}
|
|
1117
|
-
);
|
|
1219
|
+
const allTargets = stagedInstallTargets.map(item => ({
|
|
1220
|
+
target_id: item.targetId,
|
|
1221
|
+
path: item.path,
|
|
1222
|
+
}));
|
|
1223
|
+
Log.log(`[FirmwareUpdateV4] DeviceFirmwareUpdateRequest targets=${JSON.stringify(allTargets)}`);
|
|
1224
|
+
await this.protocolV2StartFirmwareUpdate({ targets: allTargets });
|
|
1225
|
+
await this.waitForProtocolV2FirmwareUpdateComplete(allTargets);
|
|
1118
1226
|
}
|
|
1119
1227
|
|
|
1120
|
-
private
|
|
1121
|
-
return
|
|
1228
|
+
private getProtocolV2InstallItemStagingPath(item: ProtocolV2InstallItem) {
|
|
1229
|
+
return `${PROTOCOL_V2_FIRMWARE_STAGING_VOLUME}${item.fileName}`;
|
|
1122
1230
|
}
|
|
1123
1231
|
|
|
1124
|
-
private async
|
|
1125
|
-
const
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1232
|
+
private async verifyProtocolV2StagedFile(path: string, expectedSize: number) {
|
|
1233
|
+
const typedCall = this.device.getCommands().typedCall.bind(this.device.getCommands());
|
|
1234
|
+
const response = await typedCall('FilesystemPathInfoQuery', 'FilesystemPathInfo', { path });
|
|
1235
|
+
const actualSize = toProtocolV2FiniteNumber(response.message?.size);
|
|
1236
|
+
if (!response.message?.exist || response.message?.directory || actualSize !== expectedSize) {
|
|
1237
|
+
throw ERRORS.TypedError(
|
|
1238
|
+
HardwareErrorCode.EmmcFileWriteFirmwareError,
|
|
1239
|
+
`staged file verification failed: path=${path} exist=${!!response.message
|
|
1240
|
+
?.exist} expected=${expectedSize} actual=${actualSize ?? 'unknown'}`
|
|
1241
|
+
);
|
|
1134
1242
|
}
|
|
1135
|
-
return false;
|
|
1136
1243
|
}
|
|
1137
1244
|
|
|
1138
1245
|
private assertProtocolV2TargetStatus(
|
|
1139
1246
|
statusTargets: ProtocolV2FirmwareUpdateStatusTarget[],
|
|
1140
1247
|
expectedTargetIds: Set<number>
|
|
1141
1248
|
) {
|
|
1249
|
+
Log.log(
|
|
1250
|
+
`[FirmwareUpdateV4] DeviceFirmwareUpdateStatus records=${JSON.stringify(statusTargets)}`
|
|
1251
|
+
);
|
|
1142
1252
|
const failedTarget = statusTargets.find(
|
|
1143
1253
|
target =>
|
|
1144
1254
|
expectedTargetIds.has(normalizeProtocolV2TargetId(target.target_id) ?? -1) &&
|
|
1145
1255
|
isProtocolV2TargetStatusFailed(target.status)
|
|
1146
1256
|
);
|
|
1147
1257
|
if (failedTarget) {
|
|
1258
|
+
const failedTargetDetails = JSON.stringify({
|
|
1259
|
+
targetId: failedTarget.target_id,
|
|
1260
|
+
status: failedTarget.status,
|
|
1261
|
+
payloadVersion: failedTarget.payload_version,
|
|
1262
|
+
path: failedTarget.path,
|
|
1263
|
+
});
|
|
1264
|
+
Log.error(`[FirmwareUpdateV4] firmware install failed target=${failedTargetDetails}`);
|
|
1148
1265
|
throw ERRORS.TypedError(
|
|
1149
1266
|
HardwareErrorCode.FirmwareError,
|
|
1150
|
-
`Protocol V2 firmware target
|
|
1267
|
+
`Protocol V2 firmware target failed: target=${failedTarget.target_id} status=${
|
|
1268
|
+
failedTarget.status ?? 'unknown'
|
|
1269
|
+
} payloadVersion=${failedTarget.payload_version ?? 'unknown'} path=${
|
|
1270
|
+
failedTarget.path ?? 'unknown'
|
|
1271
|
+
}`
|
|
1151
1272
|
);
|
|
1152
1273
|
}
|
|
1153
1274
|
|
|
1154
|
-
const
|
|
1155
|
-
target
|
|
1156
|
-
expectedTargetIds.has(normalizeProtocolV2TargetId(target.target_id) ?? -1) &&
|
|
1157
|
-
isProtocolV2TargetStatusFinished(target.status)
|
|
1275
|
+
const matchingTargets = statusTargets.filter(target =>
|
|
1276
|
+
expectedTargetIds.has(normalizeProtocolV2TargetId(target.target_id) ?? -1)
|
|
1158
1277
|
);
|
|
1159
|
-
|
|
1278
|
+
const completedTargetIds = new Set<number>();
|
|
1279
|
+
matchingTargets.forEach(target => {
|
|
1280
|
+
const targetId = normalizeProtocolV2TargetId(target.target_id);
|
|
1281
|
+
if (targetId !== undefined && isProtocolV2TargetStatusFinished(target.status)) {
|
|
1282
|
+
completedTargetIds.add(targetId);
|
|
1283
|
+
}
|
|
1284
|
+
});
|
|
1285
|
+
const allExpectedTargetsCompleted =
|
|
1286
|
+
expectedTargetIds.size > 0 &&
|
|
1287
|
+
Array.from(expectedTargetIds).every(targetId => completedTargetIds.has(targetId));
|
|
1288
|
+
if (allExpectedTargetsCompleted) {
|
|
1289
|
+
this.postProgressMessage(100, 'installingFirmware');
|
|
1160
1290
|
return true;
|
|
1161
1291
|
}
|
|
1162
1292
|
|
|
1163
|
-
|
|
1164
|
-
target =>
|
|
1165
|
-
expectedTargetIds.has(normalizeProtocolV2TargetId(target.target_id) ?? -1) &&
|
|
1293
|
+
if (expectedTargetIds.size > 0 && matchingTargets.length > 0) {
|
|
1294
|
+
const hasInProgressTarget = matchingTargets.some(target =>
|
|
1166
1295
|
isProtocolV2TargetStatusInProgress(target.status)
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1296
|
+
);
|
|
1297
|
+
const completedProgress = Math.floor(
|
|
1298
|
+
(completedTargetIds.size / expectedTargetIds.size) * 100
|
|
1299
|
+
);
|
|
1300
|
+
// The protocol exposes no per-target percentage, so report coarse progress by
|
|
1301
|
+
// completed targets and use 1% once work starts to keep the UI responsive.
|
|
1302
|
+
const progress = Math.min(99, Math.max(completedProgress, hasInProgressTarget ? 1 : 0));
|
|
1303
|
+
this.postProgressMessage(progress, 'installingFirmware');
|
|
1170
1304
|
}
|
|
1171
1305
|
|
|
1172
1306
|
return false;
|
|
1173
1307
|
}
|
|
1174
1308
|
|
|
1175
1309
|
private async waitForProtocolV2FirmwareUpdateComplete(
|
|
1176
|
-
targets: Array<{ target_id: number; path: string }
|
|
1177
|
-
startResponse?: ProtocolV2FirmwareUpdateStartResponse
|
|
1310
|
+
targets: Array<{ target_id: number; path: string }>
|
|
1178
1311
|
) {
|
|
1179
1312
|
const expectedTargetIds = new Set(targets.map(target => target.target_id));
|
|
1180
|
-
if (startResponse?.type === 'DeviceFirmwareUpdateStatus') {
|
|
1181
|
-
const statusTargets = (startResponse.message.records ??
|
|
1182
|
-
[]) as ProtocolV2FirmwareUpdateStatusTarget[];
|
|
1183
|
-
if (this.assertProtocolV2TargetStatus(statusTargets, expectedTargetIds)) {
|
|
1184
|
-
return;
|
|
1185
|
-
}
|
|
1186
|
-
}
|
|
1187
|
-
|
|
1188
1313
|
const startTime = Date.now();
|
|
1189
1314
|
let lastError: unknown;
|
|
1190
1315
|
|
|
1191
1316
|
while (Date.now() - startTime < PROTOCOL_V2_INSTALL_TIMEOUT) {
|
|
1192
1317
|
try {
|
|
1193
|
-
|
|
1194
|
-
const
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1318
|
+
await this.reconnectProtocolV2Device();
|
|
1319
|
+
const deviceInfo = await this.verifyProtocolV2ReconnectIdentity();
|
|
1320
|
+
try {
|
|
1321
|
+
const statusResponse = await this.device.getCommands().typedCall(
|
|
1322
|
+
'DeviceFirmwareUpdateStatusGet',
|
|
1323
|
+
'DeviceFirmwareUpdateStatus',
|
|
1324
|
+
{
|
|
1325
|
+
fields: {
|
|
1326
|
+
status: true,
|
|
1327
|
+
payload_version: true,
|
|
1328
|
+
path: true,
|
|
1329
|
+
},
|
|
1330
|
+
},
|
|
1331
|
+
{ timeoutMs: PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT }
|
|
1332
|
+
);
|
|
1333
|
+
if (
|
|
1334
|
+
this.assertProtocolV2TargetStatus(
|
|
1335
|
+
(statusResponse.message.records ?? []) as ProtocolV2FirmwareUpdateStatusTarget[],
|
|
1336
|
+
expectedTargetIds
|
|
1337
|
+
)
|
|
1338
|
+
) {
|
|
1339
|
+
return;
|
|
1340
|
+
}
|
|
1341
|
+
lastError = new Error('Protocol V2 firmware targets are still installing');
|
|
1342
|
+
} catch (error) {
|
|
1343
|
+
if (
|
|
1344
|
+
error instanceof HardwareError &&
|
|
1345
|
+
error.errorCode === HardwareErrorCode.FirmwareError
|
|
1346
|
+
) {
|
|
1347
|
+
throw error;
|
|
1348
|
+
}
|
|
1349
|
+
// App firmware does not register DeviceFirmwareUpdateStatusGet. Treat the
|
|
1350
|
+
// missing endpoint as completion only after the runtime probe confirms App mode.
|
|
1351
|
+
if (isProtocolV2FirmwareStatusEndpointUnavailable(error)) {
|
|
1352
|
+
if (await this.probeProtocolV2NormalMode(deviceInfo)) {
|
|
1353
|
+
Log.log(
|
|
1354
|
+
'[FirmwareUpdateV4] firmware status endpoint unavailable after confirmed App reboot'
|
|
1355
|
+
);
|
|
1209
1356
|
return;
|
|
1210
1357
|
}
|
|
1211
|
-
|
|
1212
|
-
|
|
1358
|
+
lastError = new Error(
|
|
1359
|
+
'Protocol V2 firmware status endpoint is unavailable while the device remains in loader mode'
|
|
1360
|
+
);
|
|
1361
|
+
} else {
|
|
1362
|
+
lastError = error;
|
|
1213
1363
|
Log.log(
|
|
1214
|
-
'
|
|
1215
|
-
|
|
1364
|
+
'[FirmwareUpdateV4] DeviceFirmwareUpdateStatusGet unavailable during install: ',
|
|
1365
|
+
error
|
|
1216
1366
|
);
|
|
1217
1367
|
}
|
|
1218
|
-
try {
|
|
1219
|
-
await this.pingProtocolV2Device();
|
|
1220
|
-
Log.log('Protocol V2 firmware status unavailable, Ping is ready');
|
|
1221
|
-
} catch (pingError) {
|
|
1222
|
-
lastError = pingError;
|
|
1223
|
-
Log.log('Protocol V2 firmware install Ping polling failed: ', pingError);
|
|
1224
|
-
}
|
|
1225
1368
|
}
|
|
1369
|
+
} catch (error) {
|
|
1370
|
+
lastError = error;
|
|
1371
|
+
if (this.isProtocolV2ReconnectIdentityError(error)) {
|
|
1372
|
+
throw error;
|
|
1373
|
+
}
|
|
1374
|
+
if (error instanceof HardwareError && error.errorCode === HardwareErrorCode.FirmwareError) {
|
|
1375
|
+
throw error;
|
|
1376
|
+
}
|
|
1377
|
+
Log.log('Protocol V2 firmware install device readiness probe failed: ', error);
|
|
1226
1378
|
}
|
|
1227
1379
|
await wait(1000);
|
|
1228
1380
|
}
|
|
@@ -1234,22 +1386,24 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1234
1386
|
}
|
|
1235
1387
|
|
|
1236
1388
|
private async exitProtocolV2BootloaderToNormal() {
|
|
1237
|
-
this.
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
Log.log('Protocol V2 device is already in normal mode, skip normal reboot');
|
|
1242
|
-
return;
|
|
1243
|
-
}
|
|
1244
|
-
} catch (error) {
|
|
1245
|
-
Log.log('Protocol V2 normal-mode probe before reboot failed: ', error);
|
|
1246
|
-
}
|
|
1389
|
+
await this.reconnectProtocolV2Device();
|
|
1390
|
+
await this.verifyProtocolV2ReconnectIdentity();
|
|
1391
|
+
// The connection may still be in bootloader. Request a Normal reboot directly;
|
|
1392
|
+
// repeating it after an automatic App reboot is idempotent.
|
|
1247
1393
|
await this.protocolV2Reboot(DeviceRebootType.Normal);
|
|
1248
1394
|
}
|
|
1249
1395
|
|
|
1396
|
+
private async probeProtocolV2NormalMode(deviceInfo: ProtocolV2DeviceInfo) {
|
|
1397
|
+
const features = await this.device.probeProtocolV2RuntimeState(
|
|
1398
|
+
deviceInfo,
|
|
1399
|
+
PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT
|
|
1400
|
+
);
|
|
1401
|
+
return features.mode === 'normal' && !features.bootloaderMode;
|
|
1402
|
+
}
|
|
1403
|
+
|
|
1250
1404
|
private async waitForProtocolV2FinalFeatures() {
|
|
1251
1405
|
const features = await this.waitForProtocolV2ReconnectAndFeatures(
|
|
1252
|
-
|
|
1406
|
+
PROTOCOL_V2_FINAL_RECONNECT_TIMEOUT
|
|
1253
1407
|
);
|
|
1254
1408
|
|
|
1255
1409
|
const bootloaderVersion = getDeviceBootloaderVersion(features).join('.');
|
|
@@ -1278,11 +1432,15 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1278
1432
|
const deviceInfo = await requestProtocolV2DeviceInfo({
|
|
1279
1433
|
commands: this.device.getCommands(),
|
|
1280
1434
|
timeoutMs: PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT,
|
|
1281
|
-
//
|
|
1435
|
+
// Completion needs target versions only; keep scope aligned with the request.
|
|
1282
1436
|
request: PROTOCOL_V2_VERSIONS_DEVICE_INFO_REQUEST,
|
|
1283
1437
|
});
|
|
1284
|
-
|
|
1285
|
-
|
|
1438
|
+
this.assertProtocolV2DeviceInfoIdentity(deviceInfo);
|
|
1439
|
+
const features = await this.device.probeProtocolV2RuntimeState(
|
|
1440
|
+
deviceInfo,
|
|
1441
|
+
PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT
|
|
1442
|
+
);
|
|
1443
|
+
if (features.mode !== 'normal' || features.bootloaderMode) {
|
|
1286
1444
|
throw ERRORS.TypedError(
|
|
1287
1445
|
HardwareErrorCode.DeviceNotFound,
|
|
1288
1446
|
'Protocol V2 device is still in bootloader mode'
|
|
@@ -1290,6 +1448,9 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1290
1448
|
}
|
|
1291
1449
|
return features;
|
|
1292
1450
|
} catch (error) {
|
|
1451
|
+
if (this.isProtocolV2ReconnectIdentityError(error)) {
|
|
1452
|
+
throw error;
|
|
1453
|
+
}
|
|
1293
1454
|
lastError = error;
|
|
1294
1455
|
Log.log('Protocol V2 normal mode not ready, polling Ping: ', error);
|
|
1295
1456
|
await wait(1000);
|
|
@@ -1324,15 +1485,14 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1324
1485
|
},
|
|
1325
1486
|
true
|
|
1326
1487
|
);
|
|
1327
|
-
await this.
|
|
1488
|
+
await this.ensureProtocolV2DeviceAcquired();
|
|
1328
1489
|
this.device.commands.disposed = false;
|
|
1329
1490
|
this.device.getCommands().mainId = this.device.mainId ?? '';
|
|
1330
|
-
await this.device.initialize();
|
|
1331
1491
|
return;
|
|
1332
1492
|
}
|
|
1333
1493
|
|
|
1334
|
-
// App
|
|
1335
|
-
//
|
|
1494
|
+
// App and bootloader serials may differ temporarily. During V4 reconnect, accept
|
|
1495
|
+
// only a uniquely enumerated device instead of repeatedly using the old App path.
|
|
1336
1496
|
const { deviceList } = await DevicePool.getDevices(devicesDescriptor, undefined, {
|
|
1337
1497
|
connectProtocol: PROTOCOL_V2_CONNECT_PROTOCOL,
|
|
1338
1498
|
});
|
|
@@ -1345,24 +1505,60 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1345
1505
|
deviceList[0].getConnectId()
|
|
1346
1506
|
);
|
|
1347
1507
|
this.device.updateFromCache(deviceList[0]);
|
|
1348
|
-
await this.
|
|
1508
|
+
await this.ensureProtocolV2DeviceAcquired();
|
|
1349
1509
|
this.device.commands.disposed = false;
|
|
1350
1510
|
this.device.getCommands().mainId = this.device.mainId ?? '';
|
|
1351
|
-
await this.device.initialize();
|
|
1352
1511
|
}
|
|
1353
1512
|
|
|
1354
|
-
|
|
1513
|
+
/**
|
|
1514
|
+
* After acquiring a USB session, polling reuses its command channel. Reacquire only
|
|
1515
|
+
* after reboot or enumeration changes cause hasDeviceAcquire() to become false.
|
|
1516
|
+
*/
|
|
1517
|
+
private async ensureProtocolV2DeviceAcquired() {
|
|
1518
|
+
const commands = this.device.getCommands();
|
|
1519
|
+
if (this.device.hasDeviceAcquire() && !commands.disposed) {
|
|
1520
|
+
return;
|
|
1521
|
+
}
|
|
1522
|
+
await this.device.acquire(PROTOCOL_V2_CONNECT_PROTOCOL, {
|
|
1523
|
+
throwOnRunPromiseError: true,
|
|
1524
|
+
});
|
|
1525
|
+
}
|
|
1526
|
+
|
|
1527
|
+
private isProtocolV2ReconnectIdentityError(error: unknown) {
|
|
1528
|
+
return this.normalizeErrorMessage(error).includes('Protocol V2 reconnect physical identity');
|
|
1529
|
+
}
|
|
1530
|
+
|
|
1531
|
+
private async protocolV2CommonUpdateProcess(params: ProtocolV2FileTransferParams) {
|
|
1532
|
+
let lastError: unknown;
|
|
1533
|
+
for (let attempt = 1; attempt <= PROTOCOL_V2_FILE_TRANSFER_RETRY_COUNT; attempt += 1) {
|
|
1534
|
+
try {
|
|
1535
|
+
return await this.protocolV2WriteWholeFile(params);
|
|
1536
|
+
} catch (error) {
|
|
1537
|
+
lastError = error;
|
|
1538
|
+
Log.error(
|
|
1539
|
+
`Protocol V2 file transfer failed path=${params.filePath} attempt=${attempt}/${PROTOCOL_V2_FILE_TRANSFER_RETRY_COUNT}; restarting from offset 0`,
|
|
1540
|
+
error
|
|
1541
|
+
);
|
|
1542
|
+
if (attempt === PROTOCOL_V2_FILE_TRANSFER_RETRY_COUNT) {
|
|
1543
|
+
break;
|
|
1544
|
+
}
|
|
1545
|
+
await this.recoverProtocolV2FileTransfer();
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1548
|
+
|
|
1549
|
+
throw ERRORS.TypedError(
|
|
1550
|
+
HardwareErrorCode.EmmcFileWriteFirmwareError,
|
|
1551
|
+
`transfer data error: ${getProtocolV2UnknownErrorText(lastError)}`
|
|
1552
|
+
);
|
|
1553
|
+
}
|
|
1554
|
+
|
|
1555
|
+
private async protocolV2WriteWholeFile({
|
|
1355
1556
|
payload,
|
|
1356
1557
|
filePath,
|
|
1357
1558
|
processedSize,
|
|
1358
1559
|
totalSize,
|
|
1359
1560
|
onTransferredBytes,
|
|
1360
|
-
}:
|
|
1361
|
-
filePath: string;
|
|
1362
|
-
processedSize?: number;
|
|
1363
|
-
totalSize?: number;
|
|
1364
|
-
onTransferredBytes?: (transferredBytes: number) => void;
|
|
1365
|
-
}) {
|
|
1561
|
+
}: ProtocolV2FileTransferParams) {
|
|
1366
1562
|
const chunkSize = this.getProtocolV2FirmwareChunkSize();
|
|
1367
1563
|
let offset = 0;
|
|
1368
1564
|
const getUploadProgress = (fileOffset: number) => {
|
|
@@ -1383,7 +1579,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1383
1579
|
totalSize ?? payload.byteLength
|
|
1384
1580
|
);
|
|
1385
1581
|
|
|
1386
|
-
const writeRes = await this.
|
|
1582
|
+
const writeRes = await this.fileWriteChunk(
|
|
1387
1583
|
filePath,
|
|
1388
1584
|
payload.byteLength,
|
|
1389
1585
|
offset,
|
|
@@ -1391,12 +1587,10 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1391
1587
|
overwrite,
|
|
1392
1588
|
progress
|
|
1393
1589
|
);
|
|
1394
|
-
const
|
|
1395
|
-
const
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
: offset + chunkLength;
|
|
1399
|
-
if (nextOffset <= offset || nextOffset > payload.byteLength) {
|
|
1590
|
+
const rawProcessedByte = writeRes.message.processed_byte;
|
|
1591
|
+
const processedByte = Number(rawProcessedByte);
|
|
1592
|
+
const nextOffset = rawProcessedByte === undefined ? offset + chunkLength : processedByte;
|
|
1593
|
+
if (!Number.isFinite(nextOffset) || nextOffset <= offset || nextOffset > chunkEnd) {
|
|
1400
1594
|
throw ERRORS.TypedError(
|
|
1401
1595
|
HardwareErrorCode.EmmcFileWriteFirmwareError,
|
|
1402
1596
|
`invalid processed_byte ${writeRes.message.processed_byte} for offset ${offset}`
|
|
@@ -1424,7 +1618,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1424
1618
|
return env ?? 'unknown';
|
|
1425
1619
|
}
|
|
1426
1620
|
|
|
1427
|
-
private async
|
|
1621
|
+
private async fileWriteChunk(
|
|
1428
1622
|
filePath: string,
|
|
1429
1623
|
totalFileSize: number,
|
|
1430
1624
|
offset: number,
|
|
@@ -1432,57 +1626,38 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1432
1626
|
overwrite: boolean,
|
|
1433
1627
|
progress: number | null
|
|
1434
1628
|
): Promise<TypedResponseMessage<'FilesystemFile'>> {
|
|
1435
|
-
const
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
if (writeRes.type
|
|
1449
|
-
if ((writeRes as any).
|
|
1450
|
-
|
|
1451
|
-
throw ERRORS.TypedError(HardwareErrorCode.RuntimeError, SESSION_ERROR);
|
|
1452
|
-
}
|
|
1629
|
+
const typedCall = this.device.getCommands().typedCall.bind(this.device.getCommands());
|
|
1630
|
+
const writeRes = await typedCall('FilesystemFileWrite', 'FilesystemFile', {
|
|
1631
|
+
file: {
|
|
1632
|
+
path: filePath,
|
|
1633
|
+
offset,
|
|
1634
|
+
total_size: totalFileSize,
|
|
1635
|
+
data: chunk,
|
|
1636
|
+
},
|
|
1637
|
+
overwrite,
|
|
1638
|
+
append: false,
|
|
1639
|
+
ui_percentage: progress ?? undefined,
|
|
1640
|
+
});
|
|
1641
|
+
if (writeRes.type !== 'FilesystemFile') {
|
|
1642
|
+
if ((writeRes as any).type === 'CallMethodError') {
|
|
1643
|
+
if (((writeRes as any).message.error ?? '').indexOf(SESSION_ERROR) > -1) {
|
|
1644
|
+
throw ERRORS.TypedError(HardwareErrorCode.RuntimeError, SESSION_ERROR);
|
|
1453
1645
|
}
|
|
1454
|
-
throw ERRORS.TypedError(
|
|
1455
|
-
HardwareErrorCode.EmmcFileWriteFirmwareError,
|
|
1456
|
-
'transfer data error'
|
|
1457
|
-
);
|
|
1458
1646
|
}
|
|
1459
|
-
|
|
1460
|
-
}
|
|
1647
|
+
throw ERRORS.TypedError(HardwareErrorCode.EmmcFileWriteFirmwareError, 'transfer data error');
|
|
1648
|
+
}
|
|
1649
|
+
return writeRes;
|
|
1650
|
+
}
|
|
1461
1651
|
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
return result;
|
|
1467
|
-
} catch (error) {
|
|
1468
|
-
Log.error(`fileWrite error: `, error);
|
|
1469
|
-
retryCount--;
|
|
1470
|
-
if (retryCount === 0) {
|
|
1471
|
-
throw ERRORS.TypedError(
|
|
1472
|
-
HardwareErrorCode.EmmcFileWriteFirmwareError,
|
|
1473
|
-
'transfer data error'
|
|
1474
|
-
);
|
|
1475
|
-
}
|
|
1476
|
-
const env = DataManager.getSettings('env');
|
|
1477
|
-
if (DataManager.isBleConnect(env)) {
|
|
1478
|
-
await wait(3000);
|
|
1479
|
-
await this.acquireProtocolV2BleDevice();
|
|
1480
|
-
await this.device.initialize();
|
|
1481
|
-
}
|
|
1482
|
-
await wait(2000);
|
|
1483
|
-
}
|
|
1652
|
+
private async recoverProtocolV2FileTransfer() {
|
|
1653
|
+
const env = DataManager.getSettings('env');
|
|
1654
|
+
if (DataManager.isBleConnect(env)) {
|
|
1655
|
+
await wait(3000);
|
|
1484
1656
|
}
|
|
1485
|
-
|
|
1657
|
+
await this.reconnectProtocolV2Device();
|
|
1658
|
+
await this.verifyProtocolV2ReconnectIdentity();
|
|
1659
|
+
await this.device.initialize();
|
|
1660
|
+
await wait(2000);
|
|
1486
1661
|
}
|
|
1487
1662
|
|
|
1488
1663
|
private async acquireProtocolV2BleDevice() {
|
|
@@ -1500,35 +1675,16 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1500
1675
|
targets: Array<{ target_id: number; path: string }>;
|
|
1501
1676
|
}) {
|
|
1502
1677
|
const commands = this.device.getCommands();
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
{
|
|
1512
|
-
intermediateTypes: ['DeviceFirmwareUpdateStatus'],
|
|
1513
|
-
timeoutMs: PROTOCOL_V2_START_UPDATE_TIMEOUT,
|
|
1514
|
-
onIntermediateResponse: (response: { type?: string }) => {
|
|
1515
|
-
if (response.type === 'DeviceFirmwareUpdateStatus') {
|
|
1516
|
-
this.postProgressMessage(99, 'installingFirmware');
|
|
1517
|
-
}
|
|
1518
|
-
},
|
|
1519
|
-
}
|
|
1520
|
-
);
|
|
1521
|
-
} catch (error) {
|
|
1522
|
-
if (isProtocolV2StartUpdateTransientError(error)) {
|
|
1523
|
-
Log.log(
|
|
1524
|
-
'Protocol V2 firmware update request did not return; continue status polling',
|
|
1525
|
-
error
|
|
1526
|
-
);
|
|
1527
|
-
} else {
|
|
1528
|
-
throw error;
|
|
1529
|
-
}
|
|
1530
|
-
}
|
|
1678
|
+
const response: ProtocolV2FirmwareUpdateStartResponse = await commands.typedCall(
|
|
1679
|
+
'DeviceFirmwareUpdateRequest',
|
|
1680
|
+
'Success',
|
|
1681
|
+
{ targets },
|
|
1682
|
+
{ timeoutMs: PROTOCOL_V2_START_UPDATE_TIMEOUT }
|
|
1683
|
+
);
|
|
1684
|
+
// Success acknowledges that the device accepted installation. End confirmation
|
|
1685
|
+
// and begin status polling only after receiving this ACK.
|
|
1531
1686
|
this.postTipMessage(FirmwareUpdateTipMessage.FirmwareUpdating);
|
|
1687
|
+
this.postProgressMessage(0, 'installingFirmware');
|
|
1532
1688
|
return response;
|
|
1533
1689
|
}
|
|
1534
1690
|
|
|
@@ -1538,9 +1694,11 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1538
1694
|
const res = await typedCall('DeviceReboot', 'Success', {
|
|
1539
1695
|
reboot_type: rebootType,
|
|
1540
1696
|
});
|
|
1697
|
+
this.device.markProtocolV2Reboot(rebootType);
|
|
1541
1698
|
return res.message;
|
|
1542
1699
|
} catch (error) {
|
|
1543
1700
|
if (isProtocolV2DeviceDisconnectedError(error) || isProtocolV2ReconnectProbeError(error)) {
|
|
1701
|
+
this.device.markProtocolV2Reboot(rebootType);
|
|
1544
1702
|
return { message: 'Device rebooted successfully' };
|
|
1545
1703
|
}
|
|
1546
1704
|
throw error;
|