• 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_ZIP_TIP = 0xaa,
51     BIN_UPDATE_HEAD_TIP = 0x01,
52     BIN_UPDATE_DATA_TIP = 0x12,
53     BIN_UPDATE_HASH_TIP = 0x16
54 };
55 
56 using ChunkInstallStep = enum {
57     CHUNK_INSTALL_STEP_PRE = 0,
58     CHUNK_INSTALL_STEP_DO,
59     CHUNK_INSTALL_STEP_POST
60 };
61 
62 struct BinChunkUpdateInfo {
63     std::vector<std::string> componentNames;
64     bool needNewData = false;
65     ChunkInstallStep updateStep = CHUNK_INSTALL_STEP_PRE;
66     int srcFd;
67     int targetFd;
68     std::unique_ptr<TransferParams> transferParams;
69     std::string curPartition;
70     std::string cmdLine;
71     int patitionNum;
72     Hpackage::DigestAlgorithm::DigestAlgorithmPtr algorithm;
73 };
74 
75 struct PartitionHashInfo {
76     std::map<std::string, std::string> hashValues;
77     std::map<std::string, uint64_t> dataLenInfos;
78 };
79 
80 class BinChunkUpdate {
81 public:
82     explicit BinChunkUpdate(uint32_t maxBufSize);
83     virtual ~BinChunkUpdate();
84     UpdateResultCode StartBinChunkUpdate(const uint8_t *data, uint32_t len, uint32_t &dealLen);
85 private:
86     UpdateResultCode ProcessBufferData();
87 
88     UpdateResultCode ChunkInstallPreWrite(uint8_t *data, uint32_t &len);
89     UpdateResultCode ChunkInstallDoWrite(uint8_t *data, uint32_t &len);
90     UpdateResultCode ChunkInstallPostWrite(uint8_t *data, uint32_t &len);
91 
92     UpdateResultCode UpdateBinHead(uint8_t *data, uint32_t &len);
93     UpdateResultCode UpdateBinData(uint8_t *data, uint32_t &len);
94     UpdateResultCode UpdateBinHash(uint8_t *data, uint32_t &len);
95     UpdateResultCode UpdateBinOther(uint8_t *data, uint32_t &len);
96     UpdateResultCode ProcessHeader(const uint8_t *data);
97     UpdateResultCode SkipTargetData(const uint8_t *data, uint32_t len, uint32_t &dealLen);
98 
99     bool AddRemainData(const uint8_t *data, uint32_t &len);
100     bool MoveRemainingData();
101 
102     bool ReadPartitionData(uint8_t *data, uint32_t &len);
103     bool OpenDevPath();
104     bool InitTransferParams();
105 
106     // 处理安装分区
107     bool ProcessPartition(uint8_t *data, uint32_t &len, uint32_t &offset);
108     // 处理安装命令
109     bool ProcessCmdLine(uint8_t *data, uint32_t &len, uint32_t &offset);
110     // 处理安装数据
111     bool ProcessInstallData(uint8_t *data, uint32_t &len, uint32_t &offset);
112     // 执行安装命令
113     bool ExecuteCmdLine();
114 
115     bool ProcessPartitionNum(uint8_t *data, uint32_t &len, uint32_t &offset);
116 
117     bool ProcessPartitionData(uint8_t *data, uint32_t &len, uint32_t &offset, PartitionHashInfo &hashInfos);
118 
119     bool ProcessSignature(uint8_t *data, uint32_t &len, uint32_t &offset,
120         std::vector<uint8_t> &signData);
121 
122     bool ReadHash(uint8_t *data, uint32_t &len, uint32_t &offset, std::string &hashBuf);
123 
124     bool ReadDataLength(uint8_t *data, uint32_t &len, uint32_t &offset,
125         const std::string &patition, std::map<std::string, uint64_t> &dataLenInfos);
126 
127     bool VerifySignature(std::vector<uint8_t> &signData);
128 
129     bool VerifyPartitionHashes(const PartitionHashInfo &hashInfos, std::vector<std::future<bool>> &futures);
130 
131     bool VerifyPartitionHash(const std::string& partitionName, const std::string &expectedHash,
132         const std::map<std::string, uint64_t> &dataLenInfos);
133     std::string ComputeFileHash(const std::string& partitionName, const std::map<std::string, uint64_t> &dataLenInfos);
134 
135     Hpackage::PkgManager::PkgManagerPtr pkgManager_;
136     uint8_t *buffer_ = nullptr;
137     uint32_t maxBufSize_ = 0;
138     uint32_t curlen_ = 0;
139     uint32_t offset_ = 0;
140     uint32_t skipLength_ = 0;
141     bool firstBuffer_ = true;
142 
143     std::map<ChunkInstallStep, std::function<UpdateResultCode (uint8_t *, uint32_t &)>> chunkInstallProcess_;
144     BinChunkUpdateInfo updateInfo_ {};
145 };
146 } // Updater
147 #endif /* BIN_FLOW_UPDATE */
148