• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifndef BIN_CHUNK_UPDATE
16 #define BIN_CHUNK_UPDATE
17 
18 #include <cstdio>
19 #include <functional>
20 #include <string>
21 #include <sys/wait.h>
22 #include <vector>
23 #include <map>
24 #include <future>
25 
26 #include "package/pkg_manager.h"
27 #include "applypatch/transfer_manager.h"
28 #include "pkg_package/pkg_pkgfile.h"
29 #include "pkg_manager/pkg_stream.h"
30 
31 namespace Updater {
32 
33 struct __attribute__((packed)) PkgTlvHH {
34     uint16_t type;
35     uint16_t length;
36 };
37 
38 struct __attribute__((packed)) PkgTlvHI {
39     uint16_t type;
40     uint32_t length;
41 };
42 
43 using UpdateResultCode = enum {
44     STREAM_UPDATE_SUCCESS = 0,
45     STREAM_UPDATE_FAILURE = 1,
46     STREAM_UPDATE_COMPLETE = 2
47 };
48 
49 using BinUpdateTip = enum {
50     BIN_UPDATE_HEAD_TIP = 0x01,
51     BIN_UPDATE_DATA_TIP = 0x12,
52     BIN_UPDATE_HASH_TIP = 0x16
53 };
54 
55 using ChunkInstallStep = enum {
56     CHUNK_INSTALL_STEP_PRE = 0,
57     CHUNK_INSTALL_STEP_DO,
58     CHUNK_INSTALL_STEP_POST
59 };
60 
61 struct BinChunkUpdateInfo {
62     std::vector<std::string> componentNames;
63     bool needNewData = false;
64     ChunkInstallStep updateStep = CHUNK_INSTALL_STEP_PRE;
65     int srcFd;
66     int targetFd;
67     std::unique_ptr<TransferParams> transferParams;
68     std::string curPartition;
69     std::string cmdLine;
70     int patitionNum;
71     Hpackage::DigestAlgorithm::DigestAlgorithmPtr algorithm;
72 };
73 
74 struct PartitionHashInfo {
75     std::map<std::string, std::string> hashValues;
76     std::map<std::string, uint64_t> dataLenInfos;
77 };
78 
79 class BinChunkUpdate {
80 public:
81     explicit BinChunkUpdate(uint32_t maxBufSize);
82     virtual ~BinChunkUpdate();
83     UpdateResultCode StartBinChunkUpdate(const uint8_t *data, uint32_t len, uint32_t &dealLen);
84 private:
85     UpdateResultCode ProcessBufferData();
86 
87     UpdateResultCode ChunkInstallPreWrite(uint8_t *data, uint32_t &len);
88     UpdateResultCode ChunkInstallDoWrite(uint8_t *data, uint32_t &len);
89     UpdateResultCode ChunkInstallPostWrite(uint8_t *data, uint32_t &len);
90 
91     UpdateResultCode UpdateBinHead(uint8_t *data, uint32_t &len);
92     UpdateResultCode UpdateBinData(uint8_t *data, uint32_t &len);
93     UpdateResultCode UpdateBinHash(uint8_t *data, uint32_t &len);
94     UpdateResultCode UpdateBinOther(uint8_t *data, uint32_t &len);
95 
96     bool AddRemainData(const uint8_t *data, uint32_t &len);
97     bool MoveRemainingData();
98 
99     bool ReadPartitionData(uint8_t *data, uint32_t &len);
100     bool OpenDevPath();
101     bool InitTransferParams();
102 
103     // 处理安装分区
104     bool ProcessPartition(uint8_t *data, uint32_t &len, uint32_t &offset);
105     // 处理安装命令
106     bool ProcessCmdLine(uint8_t *data, uint32_t &len, uint32_t &offset);
107     // 处理安装数据
108     bool ProcessInstallData(uint8_t *data, uint32_t &len, uint32_t &offset);
109     // 执行安装命令
110     bool ExecuteCmdLine();
111 
112     bool ProcessPartitionNum(uint8_t *data, uint32_t &len, uint32_t &offset);
113 
114     bool ProcessPartitionData(uint8_t *data, uint32_t &len, uint32_t &offset, PartitionHashInfo &hashInfos);
115 
116     bool ProcessSignature(uint8_t *data, uint32_t &len, uint32_t &offset,
117         std::vector<uint8_t> &signData);
118 
119     bool ReadHash(uint8_t *data, uint32_t &len, uint32_t &offset, std::string &hashBuf);
120 
121     bool ReadDataLength(uint8_t *data, uint32_t &len, uint32_t &offset,
122         const std::string &patition, std::map<std::string, uint64_t> &dataLenInfos);
123 
124     bool VerifySignature(std::vector<uint8_t> &signData);
125 
126     bool VerifyPartitionHashes(const PartitionHashInfo &hashInfos, std::vector<std::future<bool>> &futures);
127 
128     bool VerifyPartitionHash(const std::string& partitionName, const std::string &expectedHash,
129         const std::map<std::string, uint64_t> &dataLenInfos);
130     std::string ComputeFileHash(const std::string& partitionName, const std::map<std::string, uint64_t> &dataLenInfos);
131 
132     Hpackage::PkgManager::PkgManagerPtr pkgManager_;
133     uint8_t *buffer_ = nullptr;
134     uint32_t maxBufSize_ = 0;
135     uint32_t curlen_ = 0;
136     uint32_t offset_ = 0;
137 
138     std::map<ChunkInstallStep, std::function<UpdateResultCode (uint8_t *, uint32_t &)>> chunkInstallProcess_;
139     BinChunkUpdateInfo updateInfo_ {};
140 };
141 } // Updater
142 #endif /* BIN_FLOW_UPDATE */
143