@onekeyfe/hd-core 1.2.0-alpha.5 → 1.2.0-alpha.50
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 +390 -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 +351 -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 +293 -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 +132 -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 +1781 -0
- package/__tests__/pro2Nft.test.ts +108 -0
- package/__tests__/pro2Wallpaper.test.ts +39 -0
- package/__tests__/protocol-binding.test.ts +89 -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-resources.test.ts +284 -0
- package/__tests__/protocol-v2-ui-lifecycle.test.ts +91 -0
- package/__tests__/protocol-v2-unlock-policy.test.ts +206 -0
- package/__tests__/protocol-v2.test.ts +6162 -2544
- package/__tests__/protocolV2FileWrite.test.ts +92 -0
- package/__tests__/protocolV2UiInteraction.test.ts +329 -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 +145 -0
- package/__tests__/tron-sign-message-init.test.ts +74 -0
- package/__tests__/uiProgressThrottle.test.ts +74 -0
- package/__tests__/uiPromiseRegistry.test.ts +86 -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/DetectDeviceConnectProtocol.d.ts +7 -0
- package/dist/api/DetectDeviceConnectProtocol.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 +24 -16
- 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/FirmwareUpdateBaseMethod.d.ts +0 -1
- package/dist/api/firmware/FirmwareUpdateBaseMethod.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/firmware/uploadFirmware.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 +9 -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 +1 -0
- 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 +31 -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 +1 -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/core/uiPromiseRegistry.d.ts +4 -0
- package/dist/core/uiPromiseRegistry.d.ts.map +1 -0
- package/dist/data-manager/DataManager.d.ts +4 -1
- package/dist/data-manager/DataManager.d.ts.map +1 -1
- package/dist/data-manager/connectSettings.d.ts.map +1 -1
- package/dist/device/Device.d.ts +71 -17
- 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-promise.d.ts +4 -2
- package/dist/events/ui-promise.d.ts.map +1 -1
- package/dist/events/ui-request.d.ts +50 -4
- package/dist/events/ui-request.d.ts.map +1 -1
- package/dist/events/ui-response.d.ts +10 -2
- package/dist/events/ui-response.d.ts.map +1 -1
- package/dist/index.d.ts +1592 -794
- package/dist/index.js +8249 -3981
- package/dist/inject.d.ts +6 -1
- package/dist/inject.d.ts.map +1 -1
- package/dist/lowLevelInject.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/index.d.ts +3 -2
- package/dist/protocols/protocol-v2/index.d.ts.map +1 -1
- package/dist/protocols/protocol-v2/resources.d.ts +30 -0
- package/dist/protocols/protocol-v2/resources.d.ts.map +1 -0
- 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 +42 -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/topLevelInject.d.ts.map +1 -1
- package/dist/types/api/checkAllFirmwareRelease.d.ts +26 -4
- package/dist/types/api/checkAllFirmwareRelease.d.ts.map +1 -1
- package/dist/types/api/detectDeviceConnectProtocol.d.ts +4 -0
- package/dist/types/api/detectDeviceConnectProtocol.d.ts.map +1 -0
- 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 +7 -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 +23 -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 +1 -0
- package/dist/types/params.d.ts.map +1 -1
- package/dist/types/settings.d.ts +29 -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 +31 -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 +329 -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/DetectDeviceConnectProtocol.ts +18 -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 +17 -14
- package/src/api/FirmwareUpdateV2.ts +137 -54
- package/src/api/FirmwareUpdateV3.ts +9 -13
- package/src/api/FirmwareUpdateV4.ts +660 -580
- 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 +31 -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 +18 -14
- package/src/api/firmware/getBinary.ts +8 -3
- package/src/api/firmware/uploadFirmware.ts +17 -4
- 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 +10 -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 +10 -6
- 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 +189 -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 +17 -17
- 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 +319 -124
- package/src/core/uiPromiseRegistry.ts +41 -0
- package/src/data/messages/messages-protocol-v2.json +1138 -441
- package/src/data/messages/messages.json +286 -1
- package/src/data-manager/DataManager.ts +42 -13
- package/src/data-manager/TransportManager.ts +1 -1
- package/src/data-manager/connectSettings.ts +4 -0
- package/src/device/Device.ts +878 -292
- 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 +72 -17
- 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-promise.ts +4 -2
- package/src/events/ui-request.ts +61 -4
- package/src/events/ui-response.ts +12 -2
- package/src/inject.ts +73 -43
- package/src/lowLevelInject.ts +6 -3
- 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 +1 -1
- package/src/protocols/protocol-v2/index.ts +8 -1
- package/src/protocols/protocol-v2/resources.ts +359 -0
- package/src/protocols/protocol-v2/settingsUnlockPolicy.ts +65 -0
- package/src/protocols/protocol-v2/uiInteraction.ts +250 -0
- package/src/protocols/protocol-v2/unlockPolicy.ts +1 -0
- package/src/protocols/protocol-v2/unlockPolicyRunner.ts +124 -0
- package/src/protocols/protocol-v2/walletSession.ts +424 -0
- package/src/topLevelInject.ts +6 -3
- package/src/types/api/checkAllFirmwareRelease.ts +47 -4
- package/src/types/api/detectDeviceConnectProtocol.ts +7 -0
- 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 +26 -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 +38 -64
- package/src/types/api/kaspaSignTransaction.ts +60 -4
- package/src/types/api/openWalletSession.ts +54 -0
- package/src/types/api/protocolV2.ts +33 -141
- package/src/types/api/sessionCache.ts +19 -0
- package/src/types/device.ts +185 -7
- package/src/types/params.ts +9 -2
- package/src/types/settings.ts +59 -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 +142 -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/firmware/progressThrottle.d.ts +0 -3
- package/dist/api/firmware/progressThrottle.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/firmware/progressThrottle.ts +0 -44
- 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,13 @@
|
|
|
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
5
|
PROTOCOL_V2_WEBUSB_FILE_CHUNK_SIZE,
|
|
6
6
|
} from '@onekeyfe/hd-transport';
|
|
7
|
+
import { sha256 } from '@noble/hashes/sha256';
|
|
7
8
|
|
|
8
9
|
import { FirmwareUpdateTipMessage, UI_REQUEST } from '../events/ui-request';
|
|
10
|
+
import { validateProtocolV2FilesystemPath } from './helpers/filesystemValidation';
|
|
9
11
|
import { validateParams } from './helpers/paramsValidator';
|
|
10
12
|
import {
|
|
11
13
|
LoggerNames,
|
|
@@ -25,20 +27,27 @@ import {
|
|
|
25
27
|
} from '../protocols/protocol-v2';
|
|
26
28
|
import { requestProtocolV2DeviceInfo } from '../protocols/protocol-v2/features';
|
|
27
29
|
import {
|
|
28
|
-
|
|
30
|
+
PROTOCOL_V2_RESOURCE_DEVICE_PATHS,
|
|
31
|
+
buildProtocolV2ResourceUpdatePlan,
|
|
32
|
+
isProtocolV2ResourceFileValid,
|
|
33
|
+
readProtocolV2ResourceInventory,
|
|
34
|
+
} from '../protocols/protocol-v2/resources';
|
|
35
|
+
import {
|
|
29
36
|
getProtocolV2UnknownErrorText,
|
|
30
37
|
isProtocolV2DeviceDisconnectedError,
|
|
31
38
|
} from './protocol-v2/helpers';
|
|
32
39
|
|
|
33
|
-
import type { FirmwareUpdateV4Params } from '../types/api/firmwareUpdate';
|
|
40
|
+
import type { FirmwareUpdateV4Params, FirmwareUpdateV4Target } from '../types/api/firmwareUpdate';
|
|
34
41
|
import type { EFirmwareType } from '@onekeyfe/hd-shared';
|
|
42
|
+
import type { ProtocolV2DeviceInfo } from '@onekeyfe/hd-transport';
|
|
35
43
|
import type { PROTO } from '../constants';
|
|
36
44
|
import type { TypedResponseMessage } from '../device/DeviceCommands';
|
|
37
45
|
import type {
|
|
38
46
|
Features,
|
|
39
47
|
IFirmwareReleaseInfo,
|
|
48
|
+
IProtocolV2BootResources,
|
|
40
49
|
IProtocolV2FirmwareComponent,
|
|
41
|
-
|
|
50
|
+
IProtocolV2Resource,
|
|
42
51
|
IVersionArray,
|
|
43
52
|
} from '../types';
|
|
44
53
|
|
|
@@ -46,24 +55,27 @@ const Log = getLogger(LoggerNames.Method);
|
|
|
46
55
|
|
|
47
56
|
const SESSION_ERROR = 'session not found';
|
|
48
57
|
const PROTOCOL_V2_BOOTLOADER_RECONNECT_TIMEOUT = 60 * 1000;
|
|
58
|
+
const PROTOCOL_V2_FINAL_RECONNECT_TIMEOUT = 2 * 60 * 1000;
|
|
49
59
|
const PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT = 5 * 1000;
|
|
50
|
-
const PROTOCOL_V2_START_UPDATE_TIMEOUT = 60 * 1000;
|
|
60
|
+
const PROTOCOL_V2_START_UPDATE_TIMEOUT = 3 * 60 * 1000;
|
|
51
61
|
const PROTOCOL_V2_INSTALL_TIMEOUT = 5 * 60 * 1000;
|
|
52
62
|
const PROTOCOL_V2_TARGET_STATUS_PENDING = 0;
|
|
53
63
|
const PROTOCOL_V2_TARGET_STATUS_IN_PROGRESS = 1;
|
|
54
64
|
const PROTOCOL_V2_TARGET_STATUS_FINISHED = 2;
|
|
55
65
|
const PROTOCOL_V2_TARGET_STATUS_FAILED_MIN = 3;
|
|
56
66
|
const PROTOCOL_V2_CONNECT_PROTOCOL = 'V2';
|
|
57
|
-
const PROTOCOL_V2_FIRMWARE_STAGING_VOLUME = '
|
|
67
|
+
const PROTOCOL_V2_FIRMWARE_STAGING_VOLUME = 'vol0:/';
|
|
58
68
|
const PROTOCOL_V2_MIN_FILE_CHUNK_SIZE = 64;
|
|
59
69
|
const PROTOCOL_V2_CONNECT_RETRY_COUNT = 10;
|
|
60
70
|
const PROTOCOL_V2_CONNECT_POLL_INTERVAL = 500;
|
|
61
71
|
const PROTOCOL_V2_CONNECT_SINGLE_TIMEOUT = 75 * 1000;
|
|
62
72
|
const PROTOCOL_V2_DEVICE_INFO_READY_TIMEOUT = 60 * 1000;
|
|
73
|
+
const PROTOCOL_V2_FILE_TRANSFER_RETRY_COUNT = 3;
|
|
63
74
|
const PROTOCOL_V2_OKPP_HEADER_SIZE = 0x52a0;
|
|
64
75
|
const PROTOCOL_V2_OKPP_PAYLOAD_HASH_OFFSET = 0x200;
|
|
65
76
|
const PROTOCOL_V2_OKPP_HEADER_HASH_OFFSET = 0x240;
|
|
66
77
|
const PROTOCOL_V2_OKPP_HASH_SIZE = 64;
|
|
78
|
+
const PROTOCOL_V2_BOOT_RESOURCES_FILE_NAME = 'boot_resources.crate.okpkg';
|
|
67
79
|
|
|
68
80
|
const getProtocolV2DeviceTransferProgress = (
|
|
69
81
|
bytesBeforeChunk: number,
|
|
@@ -94,19 +106,30 @@ type ProtocolV2FirmwareUpdateStatusTarget = {
|
|
|
94
106
|
path?: string;
|
|
95
107
|
};
|
|
96
108
|
|
|
97
|
-
type ProtocolV2FirmwareUpdateStartResponse =
|
|
98
|
-
| TypedResponseMessage<'Success'>
|
|
99
|
-
| TypedResponseMessage<'DeviceFirmwareUpdateStatus'>
|
|
100
|
-
| undefined;
|
|
109
|
+
type ProtocolV2FirmwareUpdateStartResponse = TypedResponseMessage<'Success'>;
|
|
101
110
|
|
|
102
111
|
type ProtocolV2TargetBinary = { fileName: string; binary: ArrayBuffer; targetId: number };
|
|
103
112
|
type ProtocolV2InstallItem = ProtocolV2TargetBinary & {
|
|
104
|
-
kind: ProtocolV2RemoteComponentTarget['kind'];
|
|
113
|
+
kind: ProtocolV2RemoteComponentTarget['kind'] | 'boot_resources';
|
|
105
114
|
};
|
|
106
115
|
type ProtocolV2InstallTarget = ProtocolV2InstallItem & {
|
|
107
116
|
path: string;
|
|
108
117
|
};
|
|
109
118
|
|
|
119
|
+
type ProtocolV2FileTransferParams = PROTO.FirmwareUpload & {
|
|
120
|
+
filePath: string;
|
|
121
|
+
processedSize?: number;
|
|
122
|
+
totalSize?: number;
|
|
123
|
+
onTransferredBytes?: (transferredBytes: number) => void;
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
/** RESC bundle okpkg written independently to devicePath through FileWrite. */
|
|
127
|
+
type ProtocolV2ResourceBundleBinary = {
|
|
128
|
+
name: string;
|
|
129
|
+
binary: ArrayBuffer;
|
|
130
|
+
devicePath: string;
|
|
131
|
+
};
|
|
132
|
+
|
|
110
133
|
type ProtocolV2RemoteComponentBinary = ProtocolV2RemoteComponentTarget & {
|
|
111
134
|
binary: ArrayBuffer;
|
|
112
135
|
};
|
|
@@ -114,7 +137,7 @@ type ProtocolV2RemoteComponentBinary = ProtocolV2RemoteComponentTarget & {
|
|
|
114
137
|
type ProtocolV2RemoteComponentTarget = {
|
|
115
138
|
fileName: string;
|
|
116
139
|
targetId: number;
|
|
117
|
-
kind: 'bootloader' | 'firmware'
|
|
140
|
+
kind: 'bootloader' | 'firmware';
|
|
118
141
|
};
|
|
119
142
|
|
|
120
143
|
type ProtocolV2OkppHeader = {
|
|
@@ -167,18 +190,24 @@ const PROTOCOL_V2_REMOTE_COMPONENT_TARGETS: Readonly<
|
|
|
167
190
|
targetId: ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE04,
|
|
168
191
|
kind: 'firmware',
|
|
169
192
|
},
|
|
170
|
-
CRATE: {
|
|
171
|
-
fileName: 'resource.bin',
|
|
172
|
-
targetId: ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_CRATE,
|
|
173
|
-
kind: 'resource',
|
|
174
|
-
},
|
|
175
193
|
};
|
|
176
194
|
|
|
195
|
+
const PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID = new Map<number, FirmwareUpdateV4Target>([
|
|
196
|
+
[ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_BOOTLOADER, 'boot'],
|
|
197
|
+
[ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_APPLICATION_P1, 'app_v1'],
|
|
198
|
+
[ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_APPLICATION_P2, 'app_v2'],
|
|
199
|
+
[ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_COPROCESSOR, 'coprocessor'],
|
|
200
|
+
[ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE01, 'se01'],
|
|
201
|
+
[ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE02, 'se02'],
|
|
202
|
+
[ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE03, 'se03'],
|
|
203
|
+
[ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE04, 'se04'],
|
|
204
|
+
]);
|
|
205
|
+
|
|
177
206
|
const PROTOCOL_V2_ROMLOADER_UNSUPPORTED_MESSAGE =
|
|
178
207
|
'FW_MGMT_TARGET_ROMLOADER is not accepted by the current Pro2 bootloader update request. Flash romloader with the loader-specific flow instead of firmwareUpdateV4.';
|
|
179
208
|
|
|
180
|
-
// hd-transport
|
|
181
|
-
//
|
|
209
|
+
// hd-transport historically decodes scalar enums as enum-name strings.
|
|
210
|
+
// Map them back to firmware protocol values before internal comparisons.
|
|
182
211
|
const PROTOCOL_V2_TARGET_ID_BY_DECODED_NAME = new Map<string, number>(
|
|
183
212
|
Object.entries(ProtocolV2FirmwareTargetType).map(([key, value]) => [key, value])
|
|
184
213
|
);
|
|
@@ -204,25 +233,12 @@ const isProtocolV2ReconnectProbeError = (error: unknown) => {
|
|
|
204
233
|
);
|
|
205
234
|
};
|
|
206
235
|
|
|
207
|
-
const
|
|
208
|
-
const message = getProtocolV2UnknownErrorText(error).toLowerCase();
|
|
209
|
-
return (
|
|
210
|
-
isProtocolV2DeviceDisconnectedError(error) ||
|
|
211
|
-
isProtocolV2ReconnectProbeError(error) ||
|
|
212
|
-
message.includes('libusb_transfer_timed_out') ||
|
|
213
|
-
(message.includes('response timeout') && message.includes('devicefirmwareupdatestatusget')) ||
|
|
214
|
-
message.includes('device not found') ||
|
|
215
|
-
message.includes('transportnotfound')
|
|
216
|
-
);
|
|
217
|
-
};
|
|
218
|
-
|
|
219
|
-
const isProtocolV2StartUpdateTransientError = (error: unknown) => {
|
|
236
|
+
const isProtocolV2FirmwareStatusEndpointUnavailable = (error: unknown) => {
|
|
220
237
|
const message = getProtocolV2UnknownErrorText(error).toLowerCase();
|
|
221
238
|
return (
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
message.includes('
|
|
225
|
-
(message.includes('response timeout') && message.includes('devicefirmwareupdaterequest'))
|
|
239
|
+
message.includes('handler not registered') ||
|
|
240
|
+
message.includes('message handler not found') ||
|
|
241
|
+
message.includes('unsupported message')
|
|
226
242
|
);
|
|
227
243
|
};
|
|
228
244
|
|
|
@@ -263,25 +279,6 @@ const normalizeProtocolV2TargetStatus = (
|
|
|
263
279
|
|
|
264
280
|
const normalizeProtocolV2Hex = (value?: string) => value?.replace(/^0x/i, '').toLowerCase();
|
|
265
281
|
|
|
266
|
-
const versionArrayToNumber = (version?: IVersionArray) => {
|
|
267
|
-
if (!version) return undefined;
|
|
268
|
-
return version[0] * 0x10000 + version[1] * 0x100 + version[2];
|
|
269
|
-
};
|
|
270
|
-
|
|
271
|
-
const versionStringToArray = (version?: string | null): IVersionArray | undefined => {
|
|
272
|
-
if (!version) return undefined;
|
|
273
|
-
const parts = version.split('.').map(part => Number(part));
|
|
274
|
-
if (parts.length !== 3 || parts.some(part => !Number.isFinite(part))) return undefined;
|
|
275
|
-
return parts as IVersionArray;
|
|
276
|
-
};
|
|
277
|
-
|
|
278
|
-
const compareProtocolV2Versions = (current?: IVersionArray, target?: IVersionArray) => {
|
|
279
|
-
const currentNumber = versionArrayToNumber(current);
|
|
280
|
-
const targetNumber = versionArrayToNumber(target);
|
|
281
|
-
if (currentNumber === undefined || targetNumber === undefined) return undefined;
|
|
282
|
-
return currentNumber - targetNumber;
|
|
283
|
-
};
|
|
284
|
-
|
|
285
282
|
const bytesToHex = (bytes: Uint8Array) =>
|
|
286
283
|
Array.from(bytes)
|
|
287
284
|
.map(byte => byte.toString(16).padStart(2, '0'))
|
|
@@ -361,6 +358,32 @@ const parseProtocolV2OkppHeader = (bytes: Uint8Array): ProtocolV2OkppHeader | nu
|
|
|
361
358
|
};
|
|
362
359
|
};
|
|
363
360
|
|
|
361
|
+
export const isProtocolV2FirmwareFingerprintValid = (
|
|
362
|
+
binary: ArrayBuffer | Uint8Array,
|
|
363
|
+
fingerprint: string | undefined
|
|
364
|
+
) => {
|
|
365
|
+
const expectedFingerprint = normalizeProtocolV2Hex(fingerprint);
|
|
366
|
+
if (!expectedFingerprint) return true;
|
|
367
|
+
return bytesToHex(sha256(toProtocolV2Bytes(binary))) === expectedFingerprint;
|
|
368
|
+
};
|
|
369
|
+
|
|
370
|
+
export const assertProtocolV2ReconnectIdentity = (
|
|
371
|
+
expectedSerialNumber?: string,
|
|
372
|
+
actualSerialNumber?: string
|
|
373
|
+
) => {
|
|
374
|
+
// Some Pro2 loader builds omit serial_no. Reconnect still uses the same BLE
|
|
375
|
+
// descriptor or requires a uniquely enumerated USB device before this check.
|
|
376
|
+
if (!expectedSerialNumber || !actualSerialNumber) {
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
379
|
+
if (actualSerialNumber !== expectedSerialNumber) {
|
|
380
|
+
throw ERRORS.TypedError(
|
|
381
|
+
HardwareErrorCode.DeviceNotFound,
|
|
382
|
+
`Protocol V2 reconnect physical identity mismatch: expected ${expectedSerialNumber}, received ${actualSerialNumber}`
|
|
383
|
+
);
|
|
384
|
+
}
|
|
385
|
+
};
|
|
386
|
+
|
|
364
387
|
/**
|
|
365
388
|
* FirmwareUpdateV4 is the complete Protocol V2 firmware update flow.
|
|
366
389
|
*
|
|
@@ -370,9 +393,16 @@ const parseProtocolV2OkppHeader = (bytes: Uint8Array): ProtocolV2OkppHeader | nu
|
|
|
370
393
|
* - completion waits for target status to finish, reboots to normal, then polls DeviceInfo
|
|
371
394
|
*/
|
|
372
395
|
export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareUpdateV4Params> {
|
|
396
|
+
private protocolV2ExpectedSerialNumber?: string;
|
|
397
|
+
|
|
398
|
+
getSupportedProtocols() {
|
|
399
|
+
return ['V2'] as const;
|
|
400
|
+
}
|
|
401
|
+
|
|
373
402
|
init() {
|
|
374
403
|
this.allowDeviceMode = [UI_REQUEST.BOOTLOADER, UI_REQUEST.NOT_INITIALIZE];
|
|
375
404
|
this.requireDeviceMode = [];
|
|
405
|
+
this.unlockPolicy = 'unlock-before-run';
|
|
376
406
|
this.useDevicePassphraseState = false;
|
|
377
407
|
this.skipForceUpdateCheck = true;
|
|
378
408
|
|
|
@@ -393,9 +423,9 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
393
423
|
|
|
394
424
|
validateParams(payload, [
|
|
395
425
|
{ name: 'chunkSize', type: 'number' },
|
|
396
|
-
{ name: 'resourceBinaries', type: 'array', allowEmpty: true },
|
|
397
426
|
{ name: 'forcedUpdateRes', type: 'boolean' },
|
|
398
427
|
{ name: 'bootloaderBinary', type: 'buffer' },
|
|
428
|
+
{ name: 'bootResourcesBinary', type: 'buffer' },
|
|
399
429
|
{ name: 'romloaderBinary', type: 'buffer' },
|
|
400
430
|
{ name: 'applicationP1Binary', type: 'buffer' },
|
|
401
431
|
{ name: 'applicationP2Binary', type: 'buffer' },
|
|
@@ -405,13 +435,16 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
405
435
|
{ name: 'se03Binary', type: 'buffer' },
|
|
406
436
|
{ name: 'se04Binary', type: 'buffer' },
|
|
407
437
|
{ name: 'firmwareType', type: 'string' },
|
|
438
|
+
{ name: 'targetsToUpdate', type: 'array', allowEmpty: true },
|
|
408
439
|
{ name: 'platform', type: 'string' },
|
|
440
|
+
{ name: 'resourceBundleFiles', type: 'array', allowEmpty: true },
|
|
409
441
|
]);
|
|
410
442
|
|
|
411
443
|
this.params = {
|
|
412
444
|
chunkSize: payload.chunkSize,
|
|
413
445
|
forcedUpdateRes: payload.forcedUpdateRes,
|
|
414
446
|
bootloaderBinary: payload.bootloaderBinary,
|
|
447
|
+
bootResourcesBinary: payload.bootResourcesBinary,
|
|
415
448
|
romloaderBinary: payload.romloaderBinary,
|
|
416
449
|
applicationP1Binary: payload.applicationP1Binary,
|
|
417
450
|
applicationP2Binary: payload.applicationP2Binary,
|
|
@@ -420,8 +453,9 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
420
453
|
se02Binary: payload.se02Binary,
|
|
421
454
|
se03Binary: payload.se03Binary,
|
|
422
455
|
se04Binary: payload.se04Binary,
|
|
423
|
-
|
|
456
|
+
resourceBundleFiles: payload.resourceBundleFiles,
|
|
424
457
|
firmwareType: payload.firmwareType,
|
|
458
|
+
targetsToUpdate: payload.targetsToUpdate,
|
|
425
459
|
platform: payload.platform,
|
|
426
460
|
};
|
|
427
461
|
}
|
|
@@ -429,10 +463,11 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
429
463
|
private getProtocolV2FirmwareChunkSize() {
|
|
430
464
|
const payloadChunkSize = Number(this.params?.chunkSize);
|
|
431
465
|
const env = DataManager.getSettings('env');
|
|
432
|
-
const
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
466
|
+
const isBle = this.params?.platform === 'native' || (env && DataManager.isBleConnect(env));
|
|
467
|
+
let maxChunkSize = PROTOCOL_V2_WEBUSB_FILE_CHUNK_SIZE;
|
|
468
|
+
if (isBle) {
|
|
469
|
+
maxChunkSize = PROTOCOL_V2_BLE_FILE_CHUNK_SIZE;
|
|
470
|
+
}
|
|
436
471
|
if (!Number.isFinite(payloadChunkSize) || payloadChunkSize <= 0) {
|
|
437
472
|
return maxChunkSize;
|
|
438
473
|
}
|
|
@@ -443,60 +478,99 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
443
478
|
}
|
|
444
479
|
|
|
445
480
|
async run() {
|
|
446
|
-
if (!this.device.isProtocolV2()) {
|
|
447
|
-
throw ERRORS.TypedError(
|
|
448
|
-
HardwareErrorCode.RuntimeError,
|
|
449
|
-
'firmwareUpdateV4 requires a Protocol V2 device'
|
|
450
|
-
);
|
|
451
|
-
}
|
|
452
|
-
|
|
453
481
|
Log.debug('FirmwareUpdateV4 strategy: Protocol V2');
|
|
454
482
|
return this.runProtocolV2();
|
|
455
483
|
}
|
|
456
484
|
|
|
457
485
|
private async runProtocolV2() {
|
|
486
|
+
await this.captureProtocolV2PhysicalIdentity();
|
|
458
487
|
const deviceFeatures = await this.getProtocolV2DeviceFeatures();
|
|
459
488
|
const deviceFirmwareType = getFirmwareType(deviceFeatures);
|
|
460
489
|
const firmwareType = this.params.firmwareType ?? deviceFirmwareType;
|
|
490
|
+
const needsRemoteResources =
|
|
491
|
+
!this.params.resourceBundleFiles?.length &&
|
|
492
|
+
!!this.params.targetsToUpdate?.includes('resource');
|
|
461
493
|
|
|
462
|
-
let resourceBinaryMap: ProtocolV2TargetBinary[] = [];
|
|
463
494
|
let fwBinaryMap: ProtocolV2TargetBinary[] = [];
|
|
464
495
|
let bootloaderBinary: ArrayBuffer | null = null;
|
|
496
|
+
let bootResourcesInstallItem: ProtocolV2InstallItem | undefined;
|
|
465
497
|
let installItems: ProtocolV2InstallItem[] | undefined;
|
|
498
|
+
let resourceBundles: ProtocolV2ResourceBundleBinary[] | undefined;
|
|
466
499
|
try {
|
|
467
500
|
this.postTipMessage(FirmwareUpdateTipMessage.StartDownloadFirmware);
|
|
468
|
-
|
|
501
|
+
resourceBundles = this.prepareExplicitProtocolV2ResourceBundles();
|
|
469
502
|
fwBinaryMap = this.collectExplicitTargetBinaries();
|
|
470
503
|
bootloaderBinary = this.prepareBootloaderBinary();
|
|
471
|
-
|
|
504
|
+
const needsRemoteFirmware = !this.hasExplicitProtocolV2Payload(fwBinaryMap);
|
|
505
|
+
const needsRemoteBootResources =
|
|
506
|
+
!this.params.bootResourcesBinary &&
|
|
507
|
+
!!this.params.targetsToUpdate?.includes('boot_resources');
|
|
508
|
+
if (needsRemoteFirmware || needsRemoteResources || needsRemoteBootResources) {
|
|
509
|
+
// Remote updates must use a freshly fetched config before any reboot or file write.
|
|
510
|
+
await DataManager.forceReloadData();
|
|
511
|
+
}
|
|
512
|
+
if (needsRemoteFirmware) {
|
|
472
513
|
const remoteBinaries = await this.prepareRemoteProtocolV2Binaries(
|
|
473
514
|
firmwareType,
|
|
474
515
|
deviceFeatures
|
|
475
516
|
);
|
|
476
|
-
resourceBinaryMap = remoteBinaries.resourceBinaryMap;
|
|
477
517
|
bootloaderBinary = remoteBinaries.bootloaderBinary;
|
|
478
518
|
fwBinaryMap = remoteBinaries.fwBinaryMap;
|
|
479
519
|
installItems = remoteBinaries.installItems;
|
|
480
520
|
}
|
|
481
|
-
this.
|
|
521
|
+
bootResourcesInstallItem = await this.prepareProtocolV2BootResources();
|
|
522
|
+
if (bootResourcesInstallItem) {
|
|
523
|
+
installItems = [
|
|
524
|
+
bootResourcesInstallItem,
|
|
525
|
+
...(installItems ?? this.buildProtocolV2InstallItems({ bootloaderBinary, fwBinaryMap })),
|
|
526
|
+
];
|
|
527
|
+
}
|
|
528
|
+
if (!needsRemoteResources) {
|
|
529
|
+
this.postTipMessage(FirmwareUpdateTipMessage.FinishDownloadFirmware);
|
|
530
|
+
}
|
|
482
531
|
} catch (err) {
|
|
483
532
|
throw ERRORS.TypedError(HardwareErrorCode.FirmwareUpdateDownloadFailed, err.message ?? err);
|
|
484
533
|
}
|
|
485
534
|
|
|
486
|
-
if (
|
|
535
|
+
if (
|
|
536
|
+
!bootloaderBinary &&
|
|
537
|
+
fwBinaryMap.length === 0 &&
|
|
538
|
+
!installItems?.length &&
|
|
539
|
+
!resourceBundles?.length &&
|
|
540
|
+
!needsRemoteResources
|
|
541
|
+
) {
|
|
487
542
|
throw ERRORS.TypedError(
|
|
488
543
|
HardwareErrorCode.FirmwareUpdateDownloadFailed,
|
|
489
544
|
'No firmware to update'
|
|
490
545
|
);
|
|
491
546
|
}
|
|
492
547
|
|
|
493
|
-
await this.enterProtocolV2BootloaderMode();
|
|
548
|
+
const enteredBootloader = await this.enterProtocolV2BootloaderMode();
|
|
549
|
+
|
|
550
|
+
if (needsRemoteResources) {
|
|
551
|
+
try {
|
|
552
|
+
resourceBundles = await this.prepareProtocolV2ResourceBundles();
|
|
553
|
+
this.postTipMessage(FirmwareUpdateTipMessage.FinishDownloadFirmware);
|
|
554
|
+
} catch (err) {
|
|
555
|
+
if (enteredBootloader) {
|
|
556
|
+
try {
|
|
557
|
+
await this.exitProtocolV2BootloaderToNormal();
|
|
558
|
+
} catch (restoreError) {
|
|
559
|
+
Log.warn(
|
|
560
|
+
'[FirmwareUpdateV4] failed to restore App mode after resource preparation error:',
|
|
561
|
+
restoreError
|
|
562
|
+
);
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
throw ERRORS.TypedError(HardwareErrorCode.FirmwareUpdateDownloadFailed, err.message ?? err);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
494
568
|
|
|
495
569
|
await this.executeProtocolV2Update({
|
|
496
|
-
resourceBinaryMap,
|
|
497
570
|
fwBinaryMap,
|
|
498
571
|
bootloaderBinary,
|
|
499
572
|
...(installItems ? { installItems } : undefined),
|
|
573
|
+
...(resourceBundles?.length ? { resourceBundles } : undefined),
|
|
500
574
|
});
|
|
501
575
|
|
|
502
576
|
await this.exitProtocolV2BootloaderToNormal();
|
|
@@ -519,41 +593,36 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
519
593
|
throw ERRORS.TypedError(HardwareErrorCode.RuntimeError, 'Device features not available');
|
|
520
594
|
}
|
|
521
595
|
|
|
522
|
-
private
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
throw ERRORS.TypedError(
|
|
527
|
-
HardwareErrorCode.CallMethodInvalidParameter,
|
|
528
|
-
`Parameter [resourceBinaries.${index}] is of type invalid and should be [buffer].`
|
|
529
|
-
);
|
|
530
|
-
}
|
|
531
|
-
});
|
|
596
|
+
private getProtocolV2SerialNumber(deviceInfo: ProtocolV2DeviceInfo) {
|
|
597
|
+
const serialNumber = deviceInfo.hw?.serial_no?.trim();
|
|
598
|
+
return serialNumber || undefined;
|
|
599
|
+
}
|
|
532
600
|
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
601
|
+
private assertProtocolV2DeviceInfoIdentity(deviceInfo: ProtocolV2DeviceInfo) {
|
|
602
|
+
assertProtocolV2ReconnectIdentity(
|
|
603
|
+
this.protocolV2ExpectedSerialNumber,
|
|
604
|
+
this.getProtocolV2SerialNumber(deviceInfo)
|
|
605
|
+
);
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
private async requestProtocolV2PhysicalIdentity() {
|
|
609
|
+
return requestProtocolV2DeviceInfo({
|
|
610
|
+
commands: this.device.getCommands(),
|
|
611
|
+
timeoutMs: PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT,
|
|
543
612
|
});
|
|
613
|
+
}
|
|
544
614
|
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
return [];
|
|
615
|
+
private async captureProtocolV2PhysicalIdentity() {
|
|
616
|
+
const deviceInfo = await this.requestProtocolV2PhysicalIdentity();
|
|
617
|
+
const serialNumber = this.getProtocolV2SerialNumber(deviceInfo);
|
|
618
|
+
assertProtocolV2ReconnectIdentity(serialNumber, serialNumber);
|
|
619
|
+
this.protocolV2ExpectedSerialNumber = serialNumber;
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
private async verifyProtocolV2ReconnectIdentity() {
|
|
623
|
+
const deviceInfo = await this.requestProtocolV2PhysicalIdentity();
|
|
624
|
+
this.assertProtocolV2DeviceInfoIdentity(deviceInfo);
|
|
625
|
+
return deviceInfo;
|
|
557
626
|
}
|
|
558
627
|
|
|
559
628
|
private prepareBootloaderBinary(): ArrayBuffer | null {
|
|
@@ -562,25 +631,21 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
562
631
|
|
|
563
632
|
private hasExplicitProtocolV2Payload(fwBinaryMap: ProtocolV2TargetBinary[]) {
|
|
564
633
|
return (
|
|
565
|
-
!!this.params.
|
|
634
|
+
!!this.params.resourceBundleFiles?.length ||
|
|
566
635
|
!!this.params.bootloaderBinary ||
|
|
636
|
+
!!this.params.bootResourcesBinary ||
|
|
567
637
|
fwBinaryMap.length > 0
|
|
568
638
|
);
|
|
569
639
|
}
|
|
570
640
|
|
|
571
641
|
private buildProtocolV2InstallItems({
|
|
572
|
-
resourceBinaryMap,
|
|
573
642
|
bootloaderBinary,
|
|
574
643
|
fwBinaryMap,
|
|
575
644
|
}: {
|
|
576
|
-
resourceBinaryMap: ProtocolV2TargetBinary[];
|
|
577
645
|
bootloaderBinary: ArrayBuffer | null;
|
|
578
646
|
fwBinaryMap: ProtocolV2TargetBinary[];
|
|
579
647
|
}): ProtocolV2InstallItem[] {
|
|
580
|
-
const installItems: ProtocolV2InstallItem[] =
|
|
581
|
-
...resource,
|
|
582
|
-
kind: 'resource',
|
|
583
|
-
}));
|
|
648
|
+
const installItems: ProtocolV2InstallItem[] = [];
|
|
584
649
|
|
|
585
650
|
if (bootloaderBinary) {
|
|
586
651
|
installItems.push({
|
|
@@ -630,203 +695,6 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
630
695
|
return target;
|
|
631
696
|
}
|
|
632
697
|
|
|
633
|
-
private getProtocolV2ComponentTargetVersion(
|
|
634
|
-
release: IFirmwareReleaseInfo,
|
|
635
|
-
component: IProtocolV2FirmwareComponent,
|
|
636
|
-
target: ProtocolV2RemoteComponentTarget
|
|
637
|
-
) {
|
|
638
|
-
if (component.version) return component.version;
|
|
639
|
-
if (target.targetId === ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_BOOTLOADER) {
|
|
640
|
-
return release.bootloaderVersion;
|
|
641
|
-
}
|
|
642
|
-
if (
|
|
643
|
-
target.targetId === ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_APPLICATION_P1 ||
|
|
644
|
-
target.targetId === ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_APPLICATION_P2
|
|
645
|
-
) {
|
|
646
|
-
return release.version;
|
|
647
|
-
}
|
|
648
|
-
return undefined;
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
private getProtocolV2ComponentCurrentVersion(
|
|
652
|
-
features: Features,
|
|
653
|
-
target: ProtocolV2RemoteComponentTarget
|
|
654
|
-
) {
|
|
655
|
-
switch (target.targetId) {
|
|
656
|
-
case ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_BOOTLOADER:
|
|
657
|
-
return getDeviceBootloaderVersion(features);
|
|
658
|
-
case ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_APPLICATION_P1:
|
|
659
|
-
case ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_APPLICATION_P2:
|
|
660
|
-
return getDeviceFirmwareVersion(features);
|
|
661
|
-
case ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_COPROCESSOR:
|
|
662
|
-
return getDeviceBLEFirmwareVersion(features);
|
|
663
|
-
case ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE01:
|
|
664
|
-
return versionStringToArray(features.se01Version);
|
|
665
|
-
case ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE02:
|
|
666
|
-
return versionStringToArray(features.se02Version);
|
|
667
|
-
case ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE03:
|
|
668
|
-
return versionStringToArray(features.se03Version);
|
|
669
|
-
case ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_SE04:
|
|
670
|
-
return versionStringToArray(features.se04Version);
|
|
671
|
-
default:
|
|
672
|
-
return undefined;
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
private isProtocolV2ComponentVersionSatisfied(
|
|
677
|
-
release: IFirmwareReleaseInfo,
|
|
678
|
-
component: IProtocolV2FirmwareComponent,
|
|
679
|
-
target: ProtocolV2RemoteComponentTarget,
|
|
680
|
-
features: Features
|
|
681
|
-
) {
|
|
682
|
-
const targetVersion = this.getProtocolV2ComponentTargetVersion(release, component, target);
|
|
683
|
-
if (!targetVersion) return false;
|
|
684
|
-
|
|
685
|
-
const currentVersion = this.getProtocolV2ComponentCurrentVersion(features, target);
|
|
686
|
-
const compareResult = compareProtocolV2Versions(currentVersion, targetVersion);
|
|
687
|
-
return compareResult !== undefined && compareResult >= 0;
|
|
688
|
-
}
|
|
689
|
-
|
|
690
|
-
private getProtocolV2ResourceFilePath(path: string) {
|
|
691
|
-
if (path.startsWith('vol')) return path;
|
|
692
|
-
if (path.startsWith('/')) return `vol0:${path}`;
|
|
693
|
-
return `vol0:/${path}`;
|
|
694
|
-
}
|
|
695
|
-
|
|
696
|
-
private async readProtocolV2DeviceFileHeader(path: string) {
|
|
697
|
-
const typedCall = this.device.getCommands().typedCall.bind(this.device.getCommands());
|
|
698
|
-
const filePath = this.getProtocolV2ResourceFilePath(path);
|
|
699
|
-
const pathInfoRes = await typedCall('FilesystemPathInfoQuery', 'FilesystemPathInfo', {
|
|
700
|
-
path: filePath,
|
|
701
|
-
});
|
|
702
|
-
const fileSize = toProtocolV2FiniteNumber(pathInfoRes.message?.size);
|
|
703
|
-
if (
|
|
704
|
-
!pathInfoRes.message?.exist ||
|
|
705
|
-
pathInfoRes.message?.directory ||
|
|
706
|
-
fileSize === undefined ||
|
|
707
|
-
fileSize < PROTOCOL_V2_OKPP_HEADER_SIZE
|
|
708
|
-
) {
|
|
709
|
-
return null;
|
|
710
|
-
}
|
|
711
|
-
|
|
712
|
-
const chunkSize = this.getProtocolV2FirmwareChunkSize();
|
|
713
|
-
const chunks: Uint8Array[] = [];
|
|
714
|
-
let offset = 0;
|
|
715
|
-
while (offset < PROTOCOL_V2_OKPP_HEADER_SIZE) {
|
|
716
|
-
const readLen = Math.min(chunkSize, PROTOCOL_V2_OKPP_HEADER_SIZE - offset);
|
|
717
|
-
const res = await typedCall('FilesystemFileRead', 'FilesystemFile', {
|
|
718
|
-
file: {
|
|
719
|
-
path: filePath,
|
|
720
|
-
offset,
|
|
721
|
-
total_size: 0,
|
|
722
|
-
},
|
|
723
|
-
chunk_len: readLen,
|
|
724
|
-
ui_percentage: undefined,
|
|
725
|
-
});
|
|
726
|
-
const data = toProtocolV2Bytes(res.message?.data);
|
|
727
|
-
if (data.byteLength === 0) return null;
|
|
728
|
-
chunks.push(data);
|
|
729
|
-
offset += data.byteLength;
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
const headerBytes = new Uint8Array(offset);
|
|
733
|
-
let cursor = 0;
|
|
734
|
-
chunks.forEach(chunk => {
|
|
735
|
-
headerBytes.set(chunk, cursor);
|
|
736
|
-
cursor += chunk.byteLength;
|
|
737
|
-
});
|
|
738
|
-
return parseProtocolV2OkppHeader(headerBytes);
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
private async isProtocolV2ResourcePackageMatched(
|
|
742
|
-
pkg: IProtocolV2ResourceManifestPackage,
|
|
743
|
-
manifestVersion?: IVersionArray
|
|
744
|
-
) {
|
|
745
|
-
try {
|
|
746
|
-
const header = await this.readProtocolV2DeviceFileHeader(pkg.path);
|
|
747
|
-
if (!header) return false;
|
|
748
|
-
|
|
749
|
-
const expectedType = pkg.type ?? 'RESC';
|
|
750
|
-
const expectedVersion = pkg.version ?? manifestVersion;
|
|
751
|
-
if (header.type !== expectedType) return false;
|
|
752
|
-
if (expectedVersion && compareProtocolV2Versions(header.version, expectedVersion) !== 0) {
|
|
753
|
-
return false;
|
|
754
|
-
}
|
|
755
|
-
|
|
756
|
-
const expectedPayloadHash = normalizeProtocolV2Hex(pkg.payloadHash);
|
|
757
|
-
if (expectedPayloadHash && header.payloadHash !== expectedPayloadHash) return false;
|
|
758
|
-
|
|
759
|
-
const expectedHeaderHash = normalizeProtocolV2Hex(pkg.headerHash);
|
|
760
|
-
if (expectedHeaderHash && header.headerHash !== expectedHeaderHash) return false;
|
|
761
|
-
|
|
762
|
-
return true;
|
|
763
|
-
} catch (error) {
|
|
764
|
-
Log.log(`Protocol V2 resource package check failed for ${pkg.path}: `, error);
|
|
765
|
-
return false;
|
|
766
|
-
}
|
|
767
|
-
}
|
|
768
|
-
|
|
769
|
-
private async isProtocolV2ResourceManifestSatisfied(
|
|
770
|
-
manifest: IFirmwareReleaseInfo['resourceManifest']
|
|
771
|
-
) {
|
|
772
|
-
if (!manifest?.packages?.length) return false;
|
|
773
|
-
|
|
774
|
-
for (const pkg of manifest.packages) {
|
|
775
|
-
if (!(await this.isProtocolV2ResourcePackageMatched(pkg, manifest.version))) {
|
|
776
|
-
return false;
|
|
777
|
-
}
|
|
778
|
-
}
|
|
779
|
-
return true;
|
|
780
|
-
}
|
|
781
|
-
|
|
782
|
-
private getProtocolV2ResourceManifest(
|
|
783
|
-
release: IFirmwareReleaseInfo,
|
|
784
|
-
component: IProtocolV2FirmwareComponent
|
|
785
|
-
) {
|
|
786
|
-
return component.resourceManifest ?? release.resourceManifest;
|
|
787
|
-
}
|
|
788
|
-
|
|
789
|
-
private getProtocolV2ResourceComponentFileName(key: string) {
|
|
790
|
-
const safeKey = key.replace(/[^a-z0-9_-]/gi, '_') || 'resource';
|
|
791
|
-
return `resource-${safeKey}.bin`;
|
|
792
|
-
}
|
|
793
|
-
|
|
794
|
-
private async shouldInstallRemoteProtocolV2Component(
|
|
795
|
-
release: IFirmwareReleaseInfo,
|
|
796
|
-
key: string,
|
|
797
|
-
component: IProtocolV2FirmwareComponent,
|
|
798
|
-
target: ProtocolV2RemoteComponentTarget,
|
|
799
|
-
features: Features
|
|
800
|
-
) {
|
|
801
|
-
if (target.kind === 'resource') {
|
|
802
|
-
if (
|
|
803
|
-
this.params.forcedUpdateRes ||
|
|
804
|
-
features.bootloaderMode ||
|
|
805
|
-
features.mode === 'bootloader'
|
|
806
|
-
) {
|
|
807
|
-
return true;
|
|
808
|
-
}
|
|
809
|
-
const resourceMatched = await this.isProtocolV2ResourceManifestSatisfied(
|
|
810
|
-
this.getProtocolV2ResourceManifest(release, component)
|
|
811
|
-
);
|
|
812
|
-
if (resourceMatched) {
|
|
813
|
-
Log.log(`[FirmwareUpdateV4] skip Protocol V2 resource component ${key}; manifest matched`);
|
|
814
|
-
}
|
|
815
|
-
return !resourceMatched;
|
|
816
|
-
}
|
|
817
|
-
|
|
818
|
-
const versionSatisfied = this.isProtocolV2ComponentVersionSatisfied(
|
|
819
|
-
release,
|
|
820
|
-
component,
|
|
821
|
-
target,
|
|
822
|
-
features
|
|
823
|
-
);
|
|
824
|
-
if (versionSatisfied) {
|
|
825
|
-
Log.log(`[FirmwareUpdateV4] skip Protocol V2 component ${key}; version is up to date`);
|
|
826
|
-
}
|
|
827
|
-
return !versionSatisfied;
|
|
828
|
-
}
|
|
829
|
-
|
|
830
698
|
private async downloadRemoteProtocolV2Component(
|
|
831
699
|
key: string,
|
|
832
700
|
component: IProtocolV2FirmwareComponent
|
|
@@ -840,6 +708,22 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
840
708
|
}
|
|
841
709
|
|
|
842
710
|
const { binary } = await getSysResourceBinary(component.url);
|
|
711
|
+
if (!isProtocolV2FirmwareFingerprintValid(binary, component.fingerprint)) {
|
|
712
|
+
throw ERRORS.TypedError(
|
|
713
|
+
HardwareErrorCode.RuntimeError,
|
|
714
|
+
`Protocol V2 firmware fingerprint mismatch: ${key}/${component.target}`
|
|
715
|
+
);
|
|
716
|
+
}
|
|
717
|
+
const expectedPayloadHash = normalizeProtocolV2Hex(component.payloadHash);
|
|
718
|
+
if (expectedPayloadHash) {
|
|
719
|
+
const header = parseProtocolV2OkppHeader(toProtocolV2Bytes(binary));
|
|
720
|
+
if (!header || header.payloadHash !== expectedPayloadHash) {
|
|
721
|
+
throw ERRORS.TypedError(
|
|
722
|
+
HardwareErrorCode.RuntimeError,
|
|
723
|
+
`Protocol V2 firmware payload hash mismatch: ${key}/${component.target}`
|
|
724
|
+
);
|
|
725
|
+
}
|
|
726
|
+
}
|
|
843
727
|
return {
|
|
844
728
|
...target,
|
|
845
729
|
binary,
|
|
@@ -849,14 +733,12 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
849
733
|
private async prepareRemoteProtocolV2Binaries(firmwareType: EFirmwareType, features: Features) {
|
|
850
734
|
const release = DataManager.getFirmwareLatestRelease(features, firmwareType);
|
|
851
735
|
|
|
852
|
-
const resourceBinaryMap: ProtocolV2TargetBinary[] = [];
|
|
853
736
|
let bootloaderBinary: ArrayBuffer | null = null;
|
|
854
737
|
const fwBinaryMap: ProtocolV2TargetBinary[] = [];
|
|
855
738
|
const installItems: ProtocolV2InstallItem[] = [];
|
|
856
739
|
|
|
857
740
|
if (!release) {
|
|
858
741
|
return {
|
|
859
|
-
resourceBinaryMap,
|
|
860
742
|
bootloaderBinary,
|
|
861
743
|
fwBinaryMap,
|
|
862
744
|
installItems,
|
|
@@ -864,27 +746,17 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
864
746
|
}
|
|
865
747
|
|
|
866
748
|
const entries = this.getRemoteComponentEntries(release);
|
|
749
|
+
const targetsToUpdate = new Set(this.params.targetsToUpdate ?? []);
|
|
867
750
|
|
|
868
751
|
for (const [key, component] of entries) {
|
|
869
|
-
const
|
|
870
|
-
const
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
features
|
|
876
|
-
);
|
|
877
|
-
if (shouldInstall) {
|
|
752
|
+
const targetName = component.target?.toUpperCase();
|
|
753
|
+
const target = PROTOCOL_V2_REMOTE_COMPONENT_TARGETS[targetName];
|
|
754
|
+
const updateTarget = target
|
|
755
|
+
? PROTOCOL_V2_UPDATE_TARGET_BY_TARGET_ID.get(target.targetId)
|
|
756
|
+
: undefined;
|
|
757
|
+
if (updateTarget && targetsToUpdate.has(updateTarget)) {
|
|
878
758
|
const remoteBinary = await this.downloadRemoteProtocolV2Component(key, component);
|
|
879
|
-
if (remoteBinary.kind === '
|
|
880
|
-
const binaryEntry = {
|
|
881
|
-
fileName: this.getProtocolV2ResourceComponentFileName(key),
|
|
882
|
-
binary: remoteBinary.binary,
|
|
883
|
-
targetId: remoteBinary.targetId,
|
|
884
|
-
};
|
|
885
|
-
resourceBinaryMap.push(binaryEntry);
|
|
886
|
-
installItems.push({ ...binaryEntry, kind: remoteBinary.kind });
|
|
887
|
-
} else if (remoteBinary.kind === 'bootloader') {
|
|
759
|
+
if (remoteBinary.kind === 'bootloader') {
|
|
888
760
|
bootloaderBinary = remoteBinary.binary;
|
|
889
761
|
installItems.push({
|
|
890
762
|
fileName: remoteBinary.fileName,
|
|
@@ -905,23 +777,191 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
905
777
|
}
|
|
906
778
|
|
|
907
779
|
return {
|
|
908
|
-
resourceBinaryMap,
|
|
909
780
|
bootloaderBinary,
|
|
910
781
|
fwBinaryMap,
|
|
911
782
|
installItems,
|
|
912
783
|
};
|
|
913
784
|
}
|
|
914
785
|
|
|
786
|
+
private validateProtocolV2BootResourcesBinary(
|
|
787
|
+
binary: ArrayBuffer,
|
|
788
|
+
resource?: IProtocolV2BootResources
|
|
789
|
+
) {
|
|
790
|
+
if (resource && !isProtocolV2ResourceFileValid(binary, resource)) {
|
|
791
|
+
throw new Error('Pro2 boot resources file verification failed');
|
|
792
|
+
}
|
|
793
|
+
const header = parseProtocolV2OkppHeader(toProtocolV2Bytes(binary));
|
|
794
|
+
if (!header || header.type !== 'CRAT') {
|
|
795
|
+
throw new Error('Invalid Pro2 boot resources CRATE header');
|
|
796
|
+
}
|
|
797
|
+
if (resource) {
|
|
798
|
+
const expectedPayloadHash = normalizeProtocolV2Hex(resource.payloadHash);
|
|
799
|
+
const expectedHeaderHash = normalizeProtocolV2Hex(resource.headerHash);
|
|
800
|
+
if (header.payloadHash !== expectedPayloadHash) {
|
|
801
|
+
throw new Error('Pro2 boot resources payload hash mismatch');
|
|
802
|
+
}
|
|
803
|
+
if (header.headerHash !== expectedHeaderHash) {
|
|
804
|
+
throw new Error('Pro2 boot resources header hash mismatch');
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
private async prepareProtocolV2BootResources(): Promise<ProtocolV2InstallItem | undefined> {
|
|
810
|
+
let binary = this.params.bootResourcesBinary;
|
|
811
|
+
let resource: IProtocolV2BootResources | undefined;
|
|
812
|
+
|
|
813
|
+
if (!binary) {
|
|
814
|
+
if (!this.params.targetsToUpdate?.includes('boot_resources')) {
|
|
815
|
+
return undefined;
|
|
816
|
+
}
|
|
817
|
+
resource = DataManager.getProtocolV2BootResources();
|
|
818
|
+
if (!resource) {
|
|
819
|
+
throw new Error('Missing Pro2 boot resources configuration');
|
|
820
|
+
}
|
|
821
|
+
Log.log('[FirmwareUpdateV4] downloading Pro2 boot resources CRATE');
|
|
822
|
+
({ binary } = await getSysResourceBinary(resource.url));
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
this.validateProtocolV2BootResourcesBinary(binary, resource);
|
|
826
|
+
return {
|
|
827
|
+
fileName: PROTOCOL_V2_BOOT_RESOURCES_FILE_NAME,
|
|
828
|
+
binary,
|
|
829
|
+
targetId: ProtocolV2FirmwareTargetType.FW_MGMT_TARGET_CRATE,
|
|
830
|
+
kind: 'boot_resources',
|
|
831
|
+
};
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
private prepareExplicitProtocolV2ResourceBundles(): ProtocolV2ResourceBundleBinary[] | undefined {
|
|
835
|
+
if (!this.params.resourceBundleFiles?.length) return undefined;
|
|
836
|
+
|
|
837
|
+
return this.params.resourceBundleFiles.map((file, index) => {
|
|
838
|
+
const devicePath = validateProtocolV2FilesystemPath(
|
|
839
|
+
file.devicePath,
|
|
840
|
+
`resourceBundleFiles[${index}].devicePath`
|
|
841
|
+
);
|
|
842
|
+
return {
|
|
843
|
+
name: devicePath.split('/').pop() ?? devicePath,
|
|
844
|
+
binary: file.binary,
|
|
845
|
+
devicePath,
|
|
846
|
+
};
|
|
847
|
+
});
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
private async prepareProtocolV2ResourceBundles(): Promise<
|
|
851
|
+
ProtocolV2ResourceBundleBinary[] | undefined
|
|
852
|
+
> {
|
|
853
|
+
if (!this.params.targetsToUpdate?.includes('resource')) {
|
|
854
|
+
return undefined;
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
const resources = DataManager.getProtocolV2Resources();
|
|
858
|
+
if (!resources?.length) {
|
|
859
|
+
throw new Error('Missing Pro2 stable resource configuration');
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
const inventory = this.params.forcedUpdateRes
|
|
863
|
+
? undefined
|
|
864
|
+
: await readProtocolV2ResourceInventory({
|
|
865
|
+
commands: this.device.getCommands(),
|
|
866
|
+
resources,
|
|
867
|
+
chunkSize: this.getProtocolV2FirmwareChunkSize(),
|
|
868
|
+
timeoutMs: PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT,
|
|
869
|
+
});
|
|
870
|
+
const plan = buildProtocolV2ResourceUpdatePlan({
|
|
871
|
+
resources,
|
|
872
|
+
inventory,
|
|
873
|
+
mode: 'bootloader-recovery',
|
|
874
|
+
forced: this.params.forcedUpdateRes,
|
|
875
|
+
});
|
|
876
|
+
Log.log(
|
|
877
|
+
`[FirmwareUpdateV4] Pro2 resource plan mode=bootloader-recovery status=${plan.status} count=${plan.resources.length}`
|
|
878
|
+
);
|
|
879
|
+
|
|
880
|
+
const bundles: ProtocolV2ResourceBundleBinary[] = [];
|
|
881
|
+
for (const resource of plan.resources) {
|
|
882
|
+
bundles.push(await this.downloadProtocolV2Resource(resource));
|
|
883
|
+
}
|
|
884
|
+
return bundles;
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
private async downloadProtocolV2Resource(
|
|
888
|
+
resource: IProtocolV2Resource
|
|
889
|
+
): Promise<ProtocolV2ResourceBundleBinary> {
|
|
890
|
+
Log.log(`[FirmwareUpdateV4] downloading Pro2 resource ${resource.type}`);
|
|
891
|
+
const { binary } = await getSysResourceBinary(resource.url);
|
|
892
|
+
if (!isProtocolV2ResourceFileValid(binary, resource)) {
|
|
893
|
+
throw new Error(`Pro2 resource file verification failed: ${resource.type}`);
|
|
894
|
+
}
|
|
895
|
+
return {
|
|
896
|
+
name: `${resource.type}.okpkg`,
|
|
897
|
+
binary,
|
|
898
|
+
devicePath: PROTOCOL_V2_RESOURCE_DEVICE_PATHS[resource.type],
|
|
899
|
+
};
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
private async syncProtocolV2ResourceBundles(
|
|
903
|
+
bundles: ProtocolV2ResourceBundleBinary[],
|
|
904
|
+
firmwareSize: number
|
|
905
|
+
): Promise<{ processedSize: number; totalSize: number }> {
|
|
906
|
+
const transferStartTime = Date.now();
|
|
907
|
+
const transferTransport = this.getProtocolV2FirmwareTransferTransport();
|
|
908
|
+
|
|
909
|
+
// Write directly to the device through FileWrite.
|
|
910
|
+
let totalSize = 0;
|
|
911
|
+
for (const b of bundles) totalSize += b.binary.byteLength;
|
|
912
|
+
|
|
913
|
+
const transferTotalSize = totalSize + firmwareSize;
|
|
914
|
+
let processedSize = 0;
|
|
915
|
+
for (const bundle of bundles) {
|
|
916
|
+
Log.log(
|
|
917
|
+
`[FirmwareUpdateV4] syncing RESC bundle ${bundle.name} -> ${bundle.devicePath} bytes=${bundle.binary.byteLength}`
|
|
918
|
+
);
|
|
919
|
+
processedSize = await this.protocolV2CommonUpdateProcess({
|
|
920
|
+
payload: bundle.binary,
|
|
921
|
+
filePath: bundle.devicePath,
|
|
922
|
+
processedSize,
|
|
923
|
+
totalSize: transferTotalSize,
|
|
924
|
+
});
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
const elapsedMs = Date.now() - transferStartTime;
|
|
928
|
+
Log.log(
|
|
929
|
+
`[FirmwareUpdateV4] RESC bundle sync finished transport=${transferTransport} bytes=${totalSize} elapsed=${(
|
|
930
|
+
elapsedMs / 1000
|
|
931
|
+
).toFixed(2)}s speed=${formatProtocolV2TransferSpeed(totalSize, elapsedMs)} KB/s`
|
|
932
|
+
);
|
|
933
|
+
return { processedSize, totalSize: transferTotalSize };
|
|
934
|
+
}
|
|
935
|
+
|
|
915
936
|
private isProtocolV2BootloaderMode() {
|
|
916
937
|
if (typeof this.device.isBootloader === 'function') {
|
|
917
|
-
return this.device.isBootloader();
|
|
938
|
+
return !!this.device.isBootloader();
|
|
939
|
+
}
|
|
940
|
+
return (
|
|
941
|
+
this.device.features?.mode === 'bootloader' ||
|
|
942
|
+
(this.device.features?.mode == null && !!this.device.features?.bootloaderMode)
|
|
943
|
+
);
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
private isProtocolV2RomloaderMode() {
|
|
947
|
+
if (!this.device.isProtocolV2() || this.device.getCurrentDeviceType() !== EDeviceType.Pro2) {
|
|
948
|
+
return false;
|
|
949
|
+
}
|
|
950
|
+
if (typeof this.device.isRomloader === 'function') {
|
|
951
|
+
return this.device.isRomloader();
|
|
918
952
|
}
|
|
919
|
-
return
|
|
953
|
+
return this.device.features?.mode === 'romloader';
|
|
920
954
|
}
|
|
921
955
|
|
|
922
956
|
async enterProtocolV2BootloaderMode() {
|
|
957
|
+
// romloader is the first update environment and forwards targets to bootloader.
|
|
958
|
+
// It rejects DeviceRebootType.Bootloader, so reuse the current connection.
|
|
959
|
+
if (this.isProtocolV2RomloaderMode()) {
|
|
960
|
+
Log.debug('Protocol V2 device is in romloader mode; start firmware update directly');
|
|
961
|
+
return false;
|
|
962
|
+
}
|
|
923
963
|
if (this.isProtocolV2BootloaderMode()) {
|
|
924
|
-
Log.debug('Protocol V2 device is already in bootloader mode, skip reboot
|
|
964
|
+
Log.debug('Protocol V2 device is already in bootloader mode, skip reboot');
|
|
925
965
|
return false;
|
|
926
966
|
}
|
|
927
967
|
|
|
@@ -955,12 +995,19 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
955
995
|
commands: this.device.getCommands(),
|
|
956
996
|
timeoutMs: PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT,
|
|
957
997
|
});
|
|
958
|
-
|
|
959
|
-
|
|
998
|
+
this.assertProtocolV2DeviceInfoIdentity(deviceInfo);
|
|
999
|
+
const features = await this.device.probeProtocolV2RuntimeState(
|
|
1000
|
+
deviceInfo,
|
|
1001
|
+
PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT
|
|
1002
|
+
);
|
|
1003
|
+
if (features?.mode === 'bootloader') {
|
|
960
1004
|
return features;
|
|
961
1005
|
}
|
|
962
1006
|
lastError = new Error('Protocol V2 device is reachable but is not in bootloader mode');
|
|
963
1007
|
} catch (error) {
|
|
1008
|
+
if (this.isProtocolV2ReconnectIdentityError(error)) {
|
|
1009
|
+
throw error;
|
|
1010
|
+
}
|
|
964
1011
|
lastError = error;
|
|
965
1012
|
Log.log('Protocol V2 bootloader mode not ready, polling reconnect: ', error);
|
|
966
1013
|
}
|
|
@@ -976,8 +1023,8 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
976
1023
|
}
|
|
977
1024
|
|
|
978
1025
|
/**
|
|
979
|
-
*
|
|
980
|
-
*
|
|
1026
|
+
* Collect explicit target binaries grouped by DeviceFirmwareTargetType.
|
|
1027
|
+
* Filenames are display-only staging paths because target_id is explicit.
|
|
981
1028
|
*/
|
|
982
1029
|
private collectExplicitTargetBinaries() {
|
|
983
1030
|
const entries: ProtocolV2TargetBinary[] = [];
|
|
@@ -1014,30 +1061,48 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1014
1061
|
}
|
|
1015
1062
|
|
|
1016
1063
|
private async executeProtocolV2Update({
|
|
1017
|
-
resourceBinaryMap,
|
|
1018
1064
|
fwBinaryMap,
|
|
1019
1065
|
bootloaderBinary,
|
|
1020
1066
|
installItems,
|
|
1067
|
+
resourceBundles,
|
|
1021
1068
|
}: {
|
|
1022
|
-
resourceBinaryMap?: ProtocolV2TargetBinary[];
|
|
1023
1069
|
fwBinaryMap?: ProtocolV2TargetBinary[];
|
|
1024
1070
|
bootloaderBinary?: ArrayBuffer | null;
|
|
1025
1071
|
installItems?: ProtocolV2InstallItem[];
|
|
1072
|
+
resourceBundles?: ProtocolV2ResourceBundleBinary[];
|
|
1026
1073
|
}) {
|
|
1027
1074
|
const orderedInstallItems =
|
|
1028
1075
|
installItems ??
|
|
1029
1076
|
this.buildProtocolV2InstallItems({
|
|
1030
|
-
resourceBinaryMap: resourceBinaryMap ?? [],
|
|
1031
1077
|
bootloaderBinary: bootloaderBinary ?? null,
|
|
1032
1078
|
fwBinaryMap: fwBinaryMap ?? [],
|
|
1033
1079
|
});
|
|
1034
|
-
let totalSize = 0;
|
|
1035
|
-
let processedSize = 0;
|
|
1036
|
-
let transferredSize = 0;
|
|
1037
1080
|
|
|
1038
|
-
|
|
1081
|
+
let firmwareSize = 0;
|
|
1082
|
+
for (const item of orderedInstallItems) firmwareSize += item.binary.byteLength;
|
|
1039
1083
|
|
|
1040
1084
|
this.postTipMessage(FirmwareUpdateTipMessage.StartTransferData);
|
|
1085
|
+
|
|
1086
|
+
let processedSize = 0;
|
|
1087
|
+
let totalSize = firmwareSize;
|
|
1088
|
+
if (resourceBundles?.length) {
|
|
1089
|
+
const resourceTransfer = await this.syncProtocolV2ResourceBundles(
|
|
1090
|
+
resourceBundles,
|
|
1091
|
+
firmwareSize
|
|
1092
|
+
);
|
|
1093
|
+
processedSize = resourceTransfer.processedSize;
|
|
1094
|
+
totalSize = resourceTransfer.totalSize;
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1097
|
+
// Skip staging and installation when the update contains RESC bundles only.
|
|
1098
|
+
if (orderedInstallItems.length === 0) {
|
|
1099
|
+
Log.log('[FirmwareUpdateV4] no firmware targets to install (RESC bundles only)');
|
|
1100
|
+
if (totalSize > 0) {
|
|
1101
|
+
this.postProgressMessage(100, 'transferData');
|
|
1102
|
+
}
|
|
1103
|
+
return;
|
|
1104
|
+
}
|
|
1105
|
+
let transferredSize = processedSize;
|
|
1041
1106
|
const transferStartTime = Date.now();
|
|
1042
1107
|
const transferTransport = this.getProtocolV2FirmwareTransferTransport();
|
|
1043
1108
|
const chunkSize = this.getProtocolV2FirmwareChunkSize();
|
|
@@ -1064,6 +1129,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1064
1129
|
onTransferredBytes,
|
|
1065
1130
|
});
|
|
1066
1131
|
transferredSize = processedSize;
|
|
1132
|
+
await this.verifyProtocolV2StagedFile(filePath, item.binary.byteLength);
|
|
1067
1133
|
|
|
1068
1134
|
stagedInstallTargets.push({
|
|
1069
1135
|
...item,
|
|
@@ -1093,174 +1159,165 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1093
1159
|
|
|
1094
1160
|
this.postTipMessage(FirmwareUpdateTipMessage.ConfirmOnDevice);
|
|
1095
1161
|
|
|
1096
|
-
const
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
};
|
|
1104
|
-
|
|
1105
|
-
for (const item of stagedInstallTargets) {
|
|
1106
|
-
const target = {
|
|
1107
|
-
target_id: item.targetId,
|
|
1108
|
-
path: item.path,
|
|
1109
|
-
};
|
|
1110
|
-
if (item.kind === 'resource') {
|
|
1111
|
-
await flushFirmwareTargets();
|
|
1112
|
-
const resourceTargets = [target];
|
|
1113
|
-
Log.log(
|
|
1114
|
-
`[FirmwareUpdateV4] DeviceFirmwareUpdateRequest resources=${JSON.stringify(
|
|
1115
|
-
resourceTargets
|
|
1116
|
-
)}`
|
|
1117
|
-
);
|
|
1118
|
-
const startResponse = await this.protocolV2StartFirmwareUpdate({
|
|
1119
|
-
targets: resourceTargets,
|
|
1120
|
-
});
|
|
1121
|
-
await this.waitForProtocolV2FirmwareUpdateComplete(resourceTargets, startResponse);
|
|
1122
|
-
} else {
|
|
1123
|
-
firmwareTargets.push(target);
|
|
1124
|
-
}
|
|
1125
|
-
}
|
|
1126
|
-
|
|
1127
|
-
await flushFirmwareTargets();
|
|
1162
|
+
const allTargets = stagedInstallTargets.map(item => ({
|
|
1163
|
+
target_id: item.targetId,
|
|
1164
|
+
path: item.path,
|
|
1165
|
+
}));
|
|
1166
|
+
Log.log(`[FirmwareUpdateV4] DeviceFirmwareUpdateRequest targets=${JSON.stringify(allTargets)}`);
|
|
1167
|
+
await this.protocolV2StartFirmwareUpdate({ targets: allTargets });
|
|
1168
|
+
await this.waitForProtocolV2FirmwareUpdateComplete(allTargets);
|
|
1128
1169
|
}
|
|
1129
1170
|
|
|
1130
1171
|
private getProtocolV2InstallItemStagingPath(item: ProtocolV2InstallItem) {
|
|
1131
1172
|
return `${PROTOCOL_V2_FIRMWARE_STAGING_VOLUME}${item.fileName}`;
|
|
1132
1173
|
}
|
|
1133
1174
|
|
|
1134
|
-
private async
|
|
1135
|
-
const typedCall = this.device.getCommands().typedCall.bind(this.device.getCommands());
|
|
1136
|
-
return typedCall(
|
|
1137
|
-
'DeviceFirmwareUpdateStatusGet',
|
|
1138
|
-
'DeviceFirmwareUpdateStatus',
|
|
1139
|
-
{},
|
|
1140
|
-
{
|
|
1141
|
-
timeoutMs: PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT,
|
|
1142
|
-
}
|
|
1143
|
-
);
|
|
1144
|
-
}
|
|
1145
|
-
|
|
1146
|
-
private async pingProtocolV2Device() {
|
|
1175
|
+
private async verifyProtocolV2StagedFile(path: string, expectedSize: number) {
|
|
1147
1176
|
const typedCall = this.device.getCommands().typedCall.bind(this.device.getCommands());
|
|
1148
|
-
await typedCall(
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
}
|
|
1157
|
-
|
|
1158
|
-
private isProtocolV2NormalModeFeatures(features?: Features | null) {
|
|
1159
|
-
return !!features && !features.bootloaderMode && features.mode !== 'bootloader';
|
|
1160
|
-
}
|
|
1161
|
-
|
|
1162
|
-
private async probeProtocolV2NormalMode() {
|
|
1163
|
-
const deviceInfo = await requestProtocolV2DeviceInfo({
|
|
1164
|
-
commands: this.device.getCommands(),
|
|
1165
|
-
timeoutMs: PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT,
|
|
1166
|
-
request: PROTOCOL_V2_VERSIONS_DEVICE_INFO_REQUEST,
|
|
1167
|
-
});
|
|
1168
|
-
const features = this.device.updateProtocolV2Features(deviceInfo);
|
|
1169
|
-
if (this.isProtocolV2NormalModeFeatures(features)) {
|
|
1170
|
-
Log.log('Protocol V2 firmware install finished; device is back in normal mode');
|
|
1171
|
-
return true;
|
|
1177
|
+
const response = await typedCall('FilesystemPathInfoQuery', 'FilesystemPathInfo', { path });
|
|
1178
|
+
const actualSize = toProtocolV2FiniteNumber(response.message?.size);
|
|
1179
|
+
if (!response.message?.exist || response.message?.directory || actualSize !== expectedSize) {
|
|
1180
|
+
throw ERRORS.TypedError(
|
|
1181
|
+
HardwareErrorCode.EmmcFileWriteFirmwareError,
|
|
1182
|
+
`staged file verification failed: path=${path} exist=${!!response.message
|
|
1183
|
+
?.exist} expected=${expectedSize} actual=${actualSize ?? 'unknown'}`
|
|
1184
|
+
);
|
|
1172
1185
|
}
|
|
1173
|
-
return false;
|
|
1174
1186
|
}
|
|
1175
1187
|
|
|
1176
1188
|
private assertProtocolV2TargetStatus(
|
|
1177
1189
|
statusTargets: ProtocolV2FirmwareUpdateStatusTarget[],
|
|
1178
1190
|
expectedTargetIds: Set<number>
|
|
1179
1191
|
) {
|
|
1192
|
+
Log.log(
|
|
1193
|
+
`[FirmwareUpdateV4] DeviceFirmwareUpdateStatus records=${JSON.stringify(statusTargets)}`
|
|
1194
|
+
);
|
|
1180
1195
|
const failedTarget = statusTargets.find(
|
|
1181
1196
|
target =>
|
|
1182
1197
|
expectedTargetIds.has(normalizeProtocolV2TargetId(target.target_id) ?? -1) &&
|
|
1183
1198
|
isProtocolV2TargetStatusFailed(target.status)
|
|
1184
1199
|
);
|
|
1185
1200
|
if (failedTarget) {
|
|
1201
|
+
const failedTargetDetails = JSON.stringify({
|
|
1202
|
+
targetId: failedTarget.target_id,
|
|
1203
|
+
status: failedTarget.status,
|
|
1204
|
+
payloadVersion: failedTarget.payload_version,
|
|
1205
|
+
path: failedTarget.path,
|
|
1206
|
+
});
|
|
1207
|
+
Log.error(`[FirmwareUpdateV4] firmware install failed target=${failedTargetDetails}`);
|
|
1186
1208
|
throw ERRORS.TypedError(
|
|
1187
1209
|
HardwareErrorCode.FirmwareError,
|
|
1188
|
-
`Protocol V2 firmware target
|
|
1210
|
+
`Protocol V2 firmware target failed: target=${failedTarget.target_id} status=${
|
|
1211
|
+
failedTarget.status ?? 'unknown'
|
|
1212
|
+
} payloadVersion=${failedTarget.payload_version ?? 'unknown'} path=${
|
|
1213
|
+
failedTarget.path ?? 'unknown'
|
|
1214
|
+
}`
|
|
1189
1215
|
);
|
|
1190
1216
|
}
|
|
1191
1217
|
|
|
1192
|
-
const
|
|
1193
|
-
target
|
|
1194
|
-
expectedTargetIds.has(normalizeProtocolV2TargetId(target.target_id) ?? -1) &&
|
|
1195
|
-
isProtocolV2TargetStatusFinished(target.status)
|
|
1218
|
+
const matchingTargets = statusTargets.filter(target =>
|
|
1219
|
+
expectedTargetIds.has(normalizeProtocolV2TargetId(target.target_id) ?? -1)
|
|
1196
1220
|
);
|
|
1197
|
-
|
|
1221
|
+
const completedTargetIds = new Set<number>();
|
|
1222
|
+
matchingTargets.forEach(target => {
|
|
1223
|
+
const targetId = normalizeProtocolV2TargetId(target.target_id);
|
|
1224
|
+
if (targetId !== undefined && isProtocolV2TargetStatusFinished(target.status)) {
|
|
1225
|
+
completedTargetIds.add(targetId);
|
|
1226
|
+
}
|
|
1227
|
+
});
|
|
1228
|
+
const allExpectedTargetsCompleted =
|
|
1229
|
+
expectedTargetIds.size > 0 &&
|
|
1230
|
+
Array.from(expectedTargetIds).every(targetId => completedTargetIds.has(targetId));
|
|
1231
|
+
if (allExpectedTargetsCompleted) {
|
|
1232
|
+
this.postProgressMessage(100, 'installingFirmware');
|
|
1198
1233
|
return true;
|
|
1199
1234
|
}
|
|
1200
1235
|
|
|
1201
|
-
|
|
1202
|
-
target =>
|
|
1203
|
-
expectedTargetIds.has(normalizeProtocolV2TargetId(target.target_id) ?? -1) &&
|
|
1236
|
+
if (expectedTargetIds.size > 0 && matchingTargets.length > 0) {
|
|
1237
|
+
const hasInProgressTarget = matchingTargets.some(target =>
|
|
1204
1238
|
isProtocolV2TargetStatusInProgress(target.status)
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1239
|
+
);
|
|
1240
|
+
const completedProgress = Math.floor(
|
|
1241
|
+
(completedTargetIds.size / expectedTargetIds.size) * 100
|
|
1242
|
+
);
|
|
1243
|
+
// The protocol exposes no per-target percentage, so report coarse progress by
|
|
1244
|
+
// completed targets and use 1% once work starts to keep the UI responsive.
|
|
1245
|
+
const progress = Math.min(99, Math.max(completedProgress, hasInProgressTarget ? 1 : 0));
|
|
1246
|
+
this.postProgressMessage(progress, 'installingFirmware');
|
|
1208
1247
|
}
|
|
1209
1248
|
|
|
1210
1249
|
return false;
|
|
1211
1250
|
}
|
|
1212
1251
|
|
|
1213
1252
|
private async waitForProtocolV2FirmwareUpdateComplete(
|
|
1214
|
-
targets: Array<{ target_id: number; path: string }
|
|
1215
|
-
startResponse?: ProtocolV2FirmwareUpdateStartResponse
|
|
1253
|
+
targets: Array<{ target_id: number; path: string }>
|
|
1216
1254
|
) {
|
|
1217
1255
|
const expectedTargetIds = new Set(targets.map(target => target.target_id));
|
|
1218
|
-
if (startResponse?.type === 'DeviceFirmwareUpdateStatus') {
|
|
1219
|
-
const statusTargets = (startResponse.message.records ??
|
|
1220
|
-
[]) as ProtocolV2FirmwareUpdateStatusTarget[];
|
|
1221
|
-
if (this.assertProtocolV2TargetStatus(statusTargets, expectedTargetIds)) {
|
|
1222
|
-
return;
|
|
1223
|
-
}
|
|
1224
|
-
}
|
|
1225
|
-
|
|
1226
1256
|
const startTime = Date.now();
|
|
1227
1257
|
let lastError: unknown;
|
|
1228
1258
|
|
|
1229
1259
|
while (Date.now() - startTime < PROTOCOL_V2_INSTALL_TIMEOUT) {
|
|
1230
1260
|
try {
|
|
1231
|
-
|
|
1232
|
-
const
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1261
|
+
await this.reconnectProtocolV2Device();
|
|
1262
|
+
const deviceInfo = await this.verifyProtocolV2ReconnectIdentity();
|
|
1263
|
+
try {
|
|
1264
|
+
const statusResponse = await this.device.getCommands().typedCall(
|
|
1265
|
+
'DeviceFirmwareUpdateStatusGet',
|
|
1266
|
+
'DeviceFirmwareUpdateStatus',
|
|
1267
|
+
{
|
|
1268
|
+
fields: {
|
|
1269
|
+
status: true,
|
|
1270
|
+
payload_version: true,
|
|
1271
|
+
path: true,
|
|
1272
|
+
},
|
|
1273
|
+
},
|
|
1274
|
+
{ timeoutMs: PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT }
|
|
1275
|
+
);
|
|
1276
|
+
if (
|
|
1277
|
+
this.assertProtocolV2TargetStatus(
|
|
1278
|
+
(statusResponse.message.records ?? []) as ProtocolV2FirmwareUpdateStatusTarget[],
|
|
1279
|
+
expectedTargetIds
|
|
1280
|
+
)
|
|
1281
|
+
) {
|
|
1282
|
+
return;
|
|
1283
|
+
}
|
|
1284
|
+
lastError = new Error('Protocol V2 firmware targets are still installing');
|
|
1285
|
+
} catch (error) {
|
|
1286
|
+
if (
|
|
1287
|
+
error instanceof HardwareError &&
|
|
1288
|
+
error.errorCode === HardwareErrorCode.FirmwareError
|
|
1289
|
+
) {
|
|
1290
|
+
throw error;
|
|
1291
|
+
}
|
|
1292
|
+
// App firmware does not register DeviceFirmwareUpdateStatusGet. Treat the
|
|
1293
|
+
// missing endpoint as completion only after the runtime probe confirms App mode.
|
|
1294
|
+
if (isProtocolV2FirmwareStatusEndpointUnavailable(error)) {
|
|
1295
|
+
if (await this.probeProtocolV2NormalMode(deviceInfo)) {
|
|
1296
|
+
Log.log(
|
|
1297
|
+
'[FirmwareUpdateV4] firmware status endpoint unavailable after confirmed App reboot'
|
|
1298
|
+
);
|
|
1247
1299
|
return;
|
|
1248
1300
|
}
|
|
1249
|
-
|
|
1250
|
-
|
|
1301
|
+
lastError = new Error(
|
|
1302
|
+
'Protocol V2 firmware status endpoint is unavailable while the device remains in loader mode'
|
|
1303
|
+
);
|
|
1304
|
+
} else {
|
|
1305
|
+
lastError = error;
|
|
1251
1306
|
Log.log(
|
|
1252
|
-
'
|
|
1253
|
-
|
|
1307
|
+
'[FirmwareUpdateV4] DeviceFirmwareUpdateStatusGet unavailable during install: ',
|
|
1308
|
+
error
|
|
1254
1309
|
);
|
|
1255
1310
|
}
|
|
1256
|
-
try {
|
|
1257
|
-
await this.pingProtocolV2Device();
|
|
1258
|
-
Log.log('Protocol V2 firmware status unavailable, Ping is ready');
|
|
1259
|
-
} catch (pingError) {
|
|
1260
|
-
lastError = pingError;
|
|
1261
|
-
Log.log('Protocol V2 firmware install Ping polling failed: ', pingError);
|
|
1262
|
-
}
|
|
1263
1311
|
}
|
|
1312
|
+
} catch (error) {
|
|
1313
|
+
lastError = error;
|
|
1314
|
+
if (this.isProtocolV2ReconnectIdentityError(error)) {
|
|
1315
|
+
throw error;
|
|
1316
|
+
}
|
|
1317
|
+
if (error instanceof HardwareError && error.errorCode === HardwareErrorCode.FirmwareError) {
|
|
1318
|
+
throw error;
|
|
1319
|
+
}
|
|
1320
|
+
Log.log('Protocol V2 firmware install device readiness probe failed: ', error);
|
|
1264
1321
|
}
|
|
1265
1322
|
await wait(1000);
|
|
1266
1323
|
}
|
|
@@ -1272,24 +1329,30 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1272
1329
|
}
|
|
1273
1330
|
|
|
1274
1331
|
private async exitProtocolV2BootloaderToNormal() {
|
|
1275
|
-
this.
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
Log.log('Protocol V2 device is already in normal mode, skip normal reboot');
|
|
1280
|
-
return;
|
|
1281
|
-
}
|
|
1282
|
-
} catch (error) {
|
|
1283
|
-
Log.log('Protocol V2 normal-mode probe before reboot failed: ', error);
|
|
1284
|
-
}
|
|
1332
|
+
await this.reconnectProtocolV2Device();
|
|
1333
|
+
await this.verifyProtocolV2ReconnectIdentity();
|
|
1334
|
+
// The connection may still be in bootloader. Request a Normal reboot directly;
|
|
1335
|
+
// repeating it after an automatic App reboot is idempotent.
|
|
1285
1336
|
await this.protocolV2Reboot(DeviceRebootType.Normal);
|
|
1286
1337
|
}
|
|
1287
1338
|
|
|
1339
|
+
private async probeProtocolV2NormalMode(deviceInfo: ProtocolV2DeviceInfo) {
|
|
1340
|
+
const features = await this.device.probeProtocolV2RuntimeState(
|
|
1341
|
+
deviceInfo,
|
|
1342
|
+
PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT
|
|
1343
|
+
);
|
|
1344
|
+
return features.mode === 'normal' && !features.bootloaderMode;
|
|
1345
|
+
}
|
|
1346
|
+
|
|
1288
1347
|
private async waitForProtocolV2FinalFeatures() {
|
|
1289
1348
|
const features = await this.waitForProtocolV2ReconnectAndFeatures(
|
|
1290
|
-
|
|
1349
|
+
PROTOCOL_V2_FINAL_RECONNECT_TIMEOUT
|
|
1291
1350
|
);
|
|
1292
1351
|
|
|
1352
|
+
return this.getProtocolV2VersionResult(features);
|
|
1353
|
+
}
|
|
1354
|
+
|
|
1355
|
+
private getProtocolV2VersionResult(features: Features) {
|
|
1293
1356
|
const bootloaderVersion = getDeviceBootloaderVersion(features).join('.');
|
|
1294
1357
|
const bleVersion = getDeviceBLEFirmwareVersion(features).join('.');
|
|
1295
1358
|
const firmwareVersion = getDeviceFirmwareVersion(features).join('.');
|
|
@@ -1316,11 +1379,15 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1316
1379
|
const deviceInfo = await requestProtocolV2DeviceInfo({
|
|
1317
1380
|
commands: this.device.getCommands(),
|
|
1318
1381
|
timeoutMs: PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT,
|
|
1319
|
-
//
|
|
1382
|
+
// Completion needs target versions only; keep scope aligned with the request.
|
|
1320
1383
|
request: PROTOCOL_V2_VERSIONS_DEVICE_INFO_REQUEST,
|
|
1321
1384
|
});
|
|
1322
|
-
|
|
1323
|
-
|
|
1385
|
+
this.assertProtocolV2DeviceInfoIdentity(deviceInfo);
|
|
1386
|
+
const features = await this.device.probeProtocolV2RuntimeState(
|
|
1387
|
+
deviceInfo,
|
|
1388
|
+
PROTOCOL_V2_SHORT_RESPONSE_TIMEOUT
|
|
1389
|
+
);
|
|
1390
|
+
if (features.mode !== 'normal' || features.bootloaderMode) {
|
|
1324
1391
|
throw ERRORS.TypedError(
|
|
1325
1392
|
HardwareErrorCode.DeviceNotFound,
|
|
1326
1393
|
'Protocol V2 device is still in bootloader mode'
|
|
@@ -1328,6 +1395,9 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1328
1395
|
}
|
|
1329
1396
|
return features;
|
|
1330
1397
|
} catch (error) {
|
|
1398
|
+
if (this.isProtocolV2ReconnectIdentityError(error)) {
|
|
1399
|
+
throw error;
|
|
1400
|
+
}
|
|
1331
1401
|
lastError = error;
|
|
1332
1402
|
Log.log('Protocol V2 normal mode not ready, polling Ping: ', error);
|
|
1333
1403
|
await wait(1000);
|
|
@@ -1362,45 +1432,93 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1362
1432
|
},
|
|
1363
1433
|
true
|
|
1364
1434
|
);
|
|
1365
|
-
await this.
|
|
1435
|
+
await this.ensureProtocolV2DeviceAcquired();
|
|
1366
1436
|
this.device.commands.disposed = false;
|
|
1367
1437
|
this.device.getCommands().mainId = this.device.mainId ?? '';
|
|
1368
|
-
await this.device.initialize();
|
|
1369
1438
|
return;
|
|
1370
1439
|
}
|
|
1371
1440
|
|
|
1372
|
-
//
|
|
1373
|
-
//
|
|
1441
|
+
// Reinitialize every USB descriptor so DeviceInfo can provide the physical serial.
|
|
1442
|
+
// Enumeration order is not stable and must never decide the reconnect target.
|
|
1374
1443
|
const { deviceList } = await DevicePool.getDevices(devicesDescriptor, undefined, {
|
|
1375
1444
|
connectProtocol: PROTOCOL_V2_CONNECT_PROTOCOL,
|
|
1376
1445
|
});
|
|
1377
|
-
|
|
1446
|
+
const expectedSerialNumber = this.protocolV2ExpectedSerialNumber?.trim();
|
|
1447
|
+
const identityMatch = expectedSerialNumber
|
|
1448
|
+
? deviceList.find(
|
|
1449
|
+
candidate => candidate.getCurrentSerialNo?.().trim() === expectedSerialNumber
|
|
1450
|
+
)
|
|
1451
|
+
: undefined;
|
|
1452
|
+
const singleCandidate = deviceList.length === 1 ? deviceList.at(0) : undefined;
|
|
1453
|
+
const singleCandidateSerialNumber = singleCandidate?.getCurrentSerialNo?.().trim();
|
|
1454
|
+
const reconnectDevice =
|
|
1455
|
+
identityMatch ??
|
|
1456
|
+
(singleCandidate && (!expectedSerialNumber || !singleCandidateSerialNumber)
|
|
1457
|
+
? singleCandidate
|
|
1458
|
+
: undefined);
|
|
1459
|
+
if (!reconnectDevice) {
|
|
1378
1460
|
throw ERRORS.TypedError(HardwareErrorCode.DeviceNotFound);
|
|
1379
1461
|
}
|
|
1380
1462
|
|
|
1381
1463
|
Log.debug(
|
|
1382
|
-
'Protocol V2 firmware reconnect using
|
|
1383
|
-
|
|
1464
|
+
'Protocol V2 firmware reconnect using matched device:',
|
|
1465
|
+
reconnectDevice.getConnectId()
|
|
1384
1466
|
);
|
|
1385
|
-
this.device.updateFromCache(
|
|
1386
|
-
await this.
|
|
1467
|
+
this.device.updateFromCache(reconnectDevice);
|
|
1468
|
+
await this.ensureProtocolV2DeviceAcquired();
|
|
1387
1469
|
this.device.commands.disposed = false;
|
|
1388
1470
|
this.device.getCommands().mainId = this.device.mainId ?? '';
|
|
1389
|
-
await this.device.initialize();
|
|
1390
1471
|
}
|
|
1391
1472
|
|
|
1392
|
-
|
|
1473
|
+
/**
|
|
1474
|
+
* After acquiring a USB session, polling reuses its command channel. Reacquire only
|
|
1475
|
+
* after reboot or enumeration changes cause hasDeviceAcquire() to become false.
|
|
1476
|
+
*/
|
|
1477
|
+
private async ensureProtocolV2DeviceAcquired() {
|
|
1478
|
+
const commands = this.device.getCommands();
|
|
1479
|
+
if (this.device.hasDeviceAcquire() && !commands.disposed) {
|
|
1480
|
+
return;
|
|
1481
|
+
}
|
|
1482
|
+
await this.device.acquire(PROTOCOL_V2_CONNECT_PROTOCOL, {
|
|
1483
|
+
throwOnRunPromiseError: true,
|
|
1484
|
+
});
|
|
1485
|
+
}
|
|
1486
|
+
|
|
1487
|
+
private isProtocolV2ReconnectIdentityError(error: unknown) {
|
|
1488
|
+
return this.normalizeErrorMessage(error).includes('Protocol V2 reconnect physical identity');
|
|
1489
|
+
}
|
|
1490
|
+
|
|
1491
|
+
private async protocolV2CommonUpdateProcess(params: ProtocolV2FileTransferParams) {
|
|
1492
|
+
let lastError: unknown;
|
|
1493
|
+
for (let attempt = 1; attempt <= PROTOCOL_V2_FILE_TRANSFER_RETRY_COUNT; attempt += 1) {
|
|
1494
|
+
try {
|
|
1495
|
+
return await this.protocolV2WriteWholeFile(params);
|
|
1496
|
+
} catch (error) {
|
|
1497
|
+
lastError = error;
|
|
1498
|
+
Log.error(
|
|
1499
|
+
`Protocol V2 file transfer failed path=${params.filePath} attempt=${attempt}/${PROTOCOL_V2_FILE_TRANSFER_RETRY_COUNT}; restarting from offset 0`,
|
|
1500
|
+
error
|
|
1501
|
+
);
|
|
1502
|
+
if (attempt === PROTOCOL_V2_FILE_TRANSFER_RETRY_COUNT) {
|
|
1503
|
+
break;
|
|
1504
|
+
}
|
|
1505
|
+
await this.recoverProtocolV2FileTransfer();
|
|
1506
|
+
}
|
|
1507
|
+
}
|
|
1508
|
+
|
|
1509
|
+
throw ERRORS.TypedError(
|
|
1510
|
+
HardwareErrorCode.EmmcFileWriteFirmwareError,
|
|
1511
|
+
`transfer data error: ${getProtocolV2UnknownErrorText(lastError)}`
|
|
1512
|
+
);
|
|
1513
|
+
}
|
|
1514
|
+
|
|
1515
|
+
private async protocolV2WriteWholeFile({
|
|
1393
1516
|
payload,
|
|
1394
1517
|
filePath,
|
|
1395
1518
|
processedSize,
|
|
1396
1519
|
totalSize,
|
|
1397
1520
|
onTransferredBytes,
|
|
1398
|
-
}:
|
|
1399
|
-
filePath: string;
|
|
1400
|
-
processedSize?: number;
|
|
1401
|
-
totalSize?: number;
|
|
1402
|
-
onTransferredBytes?: (transferredBytes: number) => void;
|
|
1403
|
-
}) {
|
|
1521
|
+
}: ProtocolV2FileTransferParams) {
|
|
1404
1522
|
const chunkSize = this.getProtocolV2FirmwareChunkSize();
|
|
1405
1523
|
let offset = 0;
|
|
1406
1524
|
const getUploadProgress = (fileOffset: number) => {
|
|
@@ -1421,7 +1539,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1421
1539
|
totalSize ?? payload.byteLength
|
|
1422
1540
|
);
|
|
1423
1541
|
|
|
1424
|
-
const writeRes = await this.
|
|
1542
|
+
const writeRes = await this.fileWriteChunk(
|
|
1425
1543
|
filePath,
|
|
1426
1544
|
payload.byteLength,
|
|
1427
1545
|
offset,
|
|
@@ -1429,12 +1547,10 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1429
1547
|
overwrite,
|
|
1430
1548
|
progress
|
|
1431
1549
|
);
|
|
1432
|
-
const
|
|
1433
|
-
const
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
: offset + chunkLength;
|
|
1437
|
-
if (nextOffset <= offset || nextOffset > payload.byteLength) {
|
|
1550
|
+
const rawProcessedByte = writeRes.message.processed_byte;
|
|
1551
|
+
const processedByte = Number(rawProcessedByte);
|
|
1552
|
+
const nextOffset = rawProcessedByte === undefined ? offset + chunkLength : processedByte;
|
|
1553
|
+
if (!Number.isFinite(nextOffset) || nextOffset <= offset || nextOffset > chunkEnd) {
|
|
1438
1554
|
throw ERRORS.TypedError(
|
|
1439
1555
|
HardwareErrorCode.EmmcFileWriteFirmwareError,
|
|
1440
1556
|
`invalid processed_byte ${writeRes.message.processed_byte} for offset ${offset}`
|
|
@@ -1462,7 +1578,7 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1462
1578
|
return env ?? 'unknown';
|
|
1463
1579
|
}
|
|
1464
1580
|
|
|
1465
|
-
private async
|
|
1581
|
+
private async fileWriteChunk(
|
|
1466
1582
|
filePath: string,
|
|
1467
1583
|
totalFileSize: number,
|
|
1468
1584
|
offset: number,
|
|
@@ -1470,57 +1586,38 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1470
1586
|
overwrite: boolean,
|
|
1471
1587
|
progress: number | null
|
|
1472
1588
|
): Promise<TypedResponseMessage<'FilesystemFile'>> {
|
|
1473
|
-
const
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
if (writeRes.type
|
|
1487
|
-
if ((writeRes as any).
|
|
1488
|
-
|
|
1489
|
-
throw ERRORS.TypedError(HardwareErrorCode.RuntimeError, SESSION_ERROR);
|
|
1490
|
-
}
|
|
1589
|
+
const typedCall = this.device.getCommands().typedCall.bind(this.device.getCommands());
|
|
1590
|
+
const writeRes = await typedCall('FilesystemFileWrite', 'FilesystemFile', {
|
|
1591
|
+
file: {
|
|
1592
|
+
path: filePath,
|
|
1593
|
+
offset,
|
|
1594
|
+
total_size: totalFileSize,
|
|
1595
|
+
data: chunk,
|
|
1596
|
+
},
|
|
1597
|
+
overwrite,
|
|
1598
|
+
append: false,
|
|
1599
|
+
ui_percentage: progress ?? undefined,
|
|
1600
|
+
});
|
|
1601
|
+
if (writeRes.type !== 'FilesystemFile') {
|
|
1602
|
+
if ((writeRes as any).type === 'CallMethodError') {
|
|
1603
|
+
if (((writeRes as any).message.error ?? '').indexOf(SESSION_ERROR) > -1) {
|
|
1604
|
+
throw ERRORS.TypedError(HardwareErrorCode.RuntimeError, SESSION_ERROR);
|
|
1491
1605
|
}
|
|
1492
|
-
throw ERRORS.TypedError(
|
|
1493
|
-
HardwareErrorCode.EmmcFileWriteFirmwareError,
|
|
1494
|
-
'transfer data error'
|
|
1495
|
-
);
|
|
1496
1606
|
}
|
|
1497
|
-
|
|
1498
|
-
}
|
|
1607
|
+
throw ERRORS.TypedError(HardwareErrorCode.EmmcFileWriteFirmwareError, 'transfer data error');
|
|
1608
|
+
}
|
|
1609
|
+
return writeRes;
|
|
1610
|
+
}
|
|
1499
1611
|
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
return result;
|
|
1505
|
-
} catch (error) {
|
|
1506
|
-
Log.error(`fileWrite error: `, error);
|
|
1507
|
-
retryCount--;
|
|
1508
|
-
if (retryCount === 0) {
|
|
1509
|
-
throw ERRORS.TypedError(
|
|
1510
|
-
HardwareErrorCode.EmmcFileWriteFirmwareError,
|
|
1511
|
-
'transfer data error'
|
|
1512
|
-
);
|
|
1513
|
-
}
|
|
1514
|
-
const env = DataManager.getSettings('env');
|
|
1515
|
-
if (DataManager.isBleConnect(env)) {
|
|
1516
|
-
await wait(3000);
|
|
1517
|
-
await this.acquireProtocolV2BleDevice();
|
|
1518
|
-
await this.device.initialize();
|
|
1519
|
-
}
|
|
1520
|
-
await wait(2000);
|
|
1521
|
-
}
|
|
1612
|
+
private async recoverProtocolV2FileTransfer() {
|
|
1613
|
+
const env = DataManager.getSettings('env');
|
|
1614
|
+
if (DataManager.isBleConnect(env)) {
|
|
1615
|
+
await wait(3000);
|
|
1522
1616
|
}
|
|
1523
|
-
|
|
1617
|
+
await this.reconnectProtocolV2Device();
|
|
1618
|
+
await this.verifyProtocolV2ReconnectIdentity();
|
|
1619
|
+
await this.device.initialize();
|
|
1620
|
+
await wait(2000);
|
|
1524
1621
|
}
|
|
1525
1622
|
|
|
1526
1623
|
private async acquireProtocolV2BleDevice() {
|
|
@@ -1538,35 +1635,16 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1538
1635
|
targets: Array<{ target_id: number; path: string }>;
|
|
1539
1636
|
}) {
|
|
1540
1637
|
const commands = this.device.getCommands();
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
{
|
|
1550
|
-
intermediateTypes: ['DeviceFirmwareUpdateStatus'],
|
|
1551
|
-
timeoutMs: PROTOCOL_V2_START_UPDATE_TIMEOUT,
|
|
1552
|
-
onIntermediateResponse: (response: { type?: string }) => {
|
|
1553
|
-
if (response.type === 'DeviceFirmwareUpdateStatus') {
|
|
1554
|
-
this.postProgressMessage(99, 'installingFirmware');
|
|
1555
|
-
}
|
|
1556
|
-
},
|
|
1557
|
-
}
|
|
1558
|
-
);
|
|
1559
|
-
} catch (error) {
|
|
1560
|
-
if (isProtocolV2StartUpdateTransientError(error)) {
|
|
1561
|
-
Log.log(
|
|
1562
|
-
'Protocol V2 firmware update request did not return; continue status polling',
|
|
1563
|
-
error
|
|
1564
|
-
);
|
|
1565
|
-
} else {
|
|
1566
|
-
throw error;
|
|
1567
|
-
}
|
|
1568
|
-
}
|
|
1638
|
+
const response: ProtocolV2FirmwareUpdateStartResponse = await commands.typedCall(
|
|
1639
|
+
'DeviceFirmwareUpdateRequest',
|
|
1640
|
+
'Success',
|
|
1641
|
+
{ targets },
|
|
1642
|
+
{ timeoutMs: PROTOCOL_V2_START_UPDATE_TIMEOUT }
|
|
1643
|
+
);
|
|
1644
|
+
// Success acknowledges that the device accepted installation. End confirmation
|
|
1645
|
+
// and begin status polling only after receiving this ACK.
|
|
1569
1646
|
this.postTipMessage(FirmwareUpdateTipMessage.FirmwareUpdating);
|
|
1647
|
+
this.postProgressMessage(0, 'installingFirmware');
|
|
1570
1648
|
return response;
|
|
1571
1649
|
}
|
|
1572
1650
|
|
|
@@ -1576,9 +1654,11 @@ export default class FirmwareUpdateV4 extends FirmwareUpdateBaseMethod<FirmwareU
|
|
|
1576
1654
|
const res = await typedCall('DeviceReboot', 'Success', {
|
|
1577
1655
|
reboot_type: rebootType,
|
|
1578
1656
|
});
|
|
1657
|
+
this.device.markProtocolV2Reboot(rebootType);
|
|
1579
1658
|
return res.message;
|
|
1580
1659
|
} catch (error) {
|
|
1581
1660
|
if (isProtocolV2DeviceDisconnectedError(error) || isProtocolV2ReconnectProbeError(error)) {
|
|
1661
|
+
this.device.markProtocolV2Reboot(rebootType);
|
|
1582
1662
|
return { message: 'Device rebooted successfully' };
|
|
1583
1663
|
}
|
|
1584
1664
|
throw error;
|