1 /*
2 * Copyright (c) 2021 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
16 #ifndef PKG_MANAGER_H
17 #define PKG_MANAGER_H
18
19 #include <cstdlib>
20 #include <cstdio>
21 #include <functional>
22 #include <iostream>
23 #include <memory>
24 #include <vector>
25 #include "ring_buffer/ring_buffer.h"
26 #include "package/package.h"
27 #include "pkg_info_utils.h"
28
29 namespace Hpackage {
30 class PkgFile;
31 class PkgStream;
32 class PkgEntry;
33 using PkgFilePtr = PkgFile *;
34 using PkgStreamPtr = PkgStream *;
35 using PkgEntryPtr = PkgEntry *;
36
37 struct AppPkgInfo {
38 std::string packagePath;
39 std::string pkgType;
40 std::string keyPath;
41 uint8_t type;
42 };
43
44 /**
45 * Input and output stream definition
46 */
47 class PkgStream {
48 public:
49 enum {
50 PkgStreamType_Read = 0, // common file reading
51 PkgStreamType_Write, // common file writing (A new file is created and the original content is deleted.)
52 PkgStreamType_MemoryMap, // memory mapping
53 PkgStreamType_Process, // processing while parsing
54 PkgStreamType_Buffer, // buffer
55 PKgStreamType_FileMap, // file map to memory
56 PkgStreamType_FlowData, // flow data
57 };
58
59 virtual ~PkgStream() = default;
60
61 /**
62 * Read files.
63 *
64 * @param buff buffer to hold the output file content
65 * @param start start position of reading
66 * @param needRead size of the data to read
67 * @param readLen length of the read data
68 * @return file reading result
69 */
70 virtual int32_t Read(PkgBuffer &data, size_t start, size_t needRead, size_t &readLen) = 0;
71
72 /**
73 * write stream
74 *
75 * @param data buffer to hold the output file content
76 * @param size size of the data to read
77 * @param start start position of reading
78 * @return file reading result
79 */
80 virtual int32_t Write(const PkgBuffer &data, size_t size, size_t start) = 0;
81
82 virtual int32_t Flush(size_t size) = 0;
83
84 virtual int32_t GetBuffer(PkgBuffer &buffer) const = 0;
85
86 virtual size_t GetFileLength() = 0;
87 virtual const std::string GetFileName() const = 0;
88 virtual int32_t GetStreamType() const = 0;
89
90 virtual void AddRef() = 0;
91 virtual void DelRef() = 0;
92 virtual bool IsRef() const = 0;
93
94 using ExtractFileProcessor = std::function<int(const PkgBuffer &data, size_t size, size_t start,
95 bool isFinish, const void *context)>;
96
GetBuffer(uint8_t * & buffer,size_t & size)97 int32_t GetBuffer(uint8_t *&buffer, size_t &size)
98 {
99 PkgBuffer data = {};
100 int ret = GetBuffer(data);
101 buffer = data.buffer;
102 size = data.length;
103 return ret;
104 }
105
GetReadOffset()106 virtual size_t GetReadOffset() const
107 {
108 return 0;
109 }
110
Stop()111 virtual void Stop()
112 {
113 return;
114 }
115 };
116
117 class PkgFile {
118 public:
119 enum PkgType {
120 PKG_TYPE_NONE = PKG_PACK_TYPE_NONE,
121 PKG_TYPE_UPGRADE = PKG_PACK_TYPE_UPGRADE, // 升级包
122 PKG_TYPE_ZIP = PKG_PACK_TYPE_ZIP, // zip压缩包
123 PKG_TYPE_LZ4 = PKG_PACK_TYPE_LZ4, // lz4压缩包
124 PKG_TYPE_GZIP = PKG_PACK_TYPE_GZIP, // gzip压缩包
125 PKG_TYPE_MAX
126 };
127
128 using VerifyFunction = std::function<int(const PkgInfoPtr info,
129 const std::vector<uint8_t> &digest, const std::vector<uint8_t> &signature)>;
130
131 public:
132 virtual ~PkgFile() = default;
133
134 virtual int32_t AddEntry(const FileInfoPtr file, const PkgStreamPtr input) = 0;
135
136 virtual int32_t SavePackage(size_t &signOffset) = 0;
137
138 virtual int32_t ExtractFile(const PkgEntryPtr node, const PkgStreamPtr output) = 0;
139
140 virtual int32_t LoadPackage(std::vector<std::string> &fileNames, VerifyFunction verifier = nullptr) = 0;
141
142 virtual int32_t ParseComponents(std::vector<std::string> &fileNames) = 0;
143
144 virtual PkgEntryPtr FindPkgEntry(const std::string &fileName) = 0;
145
146 virtual PkgStreamPtr GetPkgStream() const = 0;
147
148 virtual const PkgInfo *GetPkgInfo() const = 0;
149
150 virtual PkgType GetPkgType() const = 0;
151
152 virtual void ClearPkgStream() = 0;
153
154 virtual int32_t ReadImgHashDataFile(const std::string &pkgType) = 0;
155 };
156
157 class PkgEntry {
158 public:
PkgEntry(PkgFilePtr pkgFile,uint32_t nodeId)159 PkgEntry(PkgFilePtr pkgFile, uint32_t nodeId) : nodeId_(nodeId), pkgFile_(pkgFile) {}
160
~PkgEntry()161 virtual ~PkgEntry() {}
162
163 virtual int32_t Init(const FileInfoPtr fileInfo, PkgStreamPtr inStream) = 0;
164
165 virtual int32_t EncodeHeader(PkgStreamPtr inStream, size_t startOffset, size_t &encodeLen) = 0;
166
167 virtual int32_t Pack(PkgStreamPtr inStream, size_t startOffset, size_t &encodeLen) = 0;
168
169 virtual int32_t DecodeHeader(PkgBuffer &buffer, size_t headerOffset, size_t dataOffset,
170 size_t &decodeLen) = 0;
171
172 virtual int32_t Unpack(PkgStreamPtr outStream) = 0;
173
GetFileName()174 virtual const std::string GetFileName() const
175 {
176 return fileName_;
177 };
178
179 virtual const FileInfo *GetFileInfo() const = 0;
180
GetPkgFile()181 PkgFilePtr GetPkgFile() const
182 {
183 return pkgFile_;
184 }
185
GetNodeId()186 uint32_t GetNodeId() const
187 {
188 return nodeId_;
189 }
190
AddDataOffset(size_t offset)191 void AddDataOffset(size_t offset)
192 {
193 dataOffset_ += offset;
194 }
195
GetFileNum()196 uint32_t GetFileNum()
197 {
198 return fileNum_;
199 }
200
SetFileNum(uint32_t num)201 void SetFileNum(uint32_t num)
202 {
203 fileNum_ = num;
204 }
205
206 protected:
207 int32_t Init(FileInfoPtr localFileInfo, const FileInfoPtr fileInfo,
208 PkgStreamPtr inStream);
209
210 protected:
211 uint32_t nodeId_ {0};
212 PkgFilePtr pkgFile_ {nullptr};
213 size_t headerOffset_ {0};
214 size_t dataOffset_ {0};
215 std::string fileName_ {};
216 uint32_t fileNum_ = 0;
217 };
218
219 using PkgDecodeProgress = std::function<void(int type, size_t writeDataLen, const void *context)>;
220
221 /**
222 * Get a singleton PkgManager instance.
223 */
224 class PkgManager {
225 public:
226 using PkgManagerPtr = PkgManager *;
227 using FileInfoPtr = FileInfo *;
228 using PkgInfoPtr = PkgInfo *;
229 using StreamPtr = PkgStream *;
230 using VerifyCallback = std::function<void(int32_t result, uint32_t percent)>;
231 using PkgFileConstructor = std::function<PkgFilePtr(
232 PkgManagerPtr manager, PkgStreamPtr stream, PkgManager::PkgInfoPtr header)>;
233
234 class PkgManagerFactory {
235 public:
236 virtual ~PkgManagerFactory() = default;
237 virtual PkgManagerPtr CreatePackageManager(void) const;
238 virtual void ReleasePkgManager(PkgManagerPtr pkgManger) const;
239 };
240
241 virtual ~PkgManager() = default;
242
243 virtual void RegisterPkgFileCreator(const std::string &fileType, PkgFileConstructor constructor) = 0;
244
245 static PkgManagerPtr CreatePackageInstance();
246 static PkgManagerPtr GetPackageInstance();
247 static void ReleasePackageInstance(PkgManagerPtr manager);
248
249 /**
250 * Create an update package based on specified parameters.
251 *
252 * @param path path of the update package
253 * @param header header, which mainly consists of algorithm information
254 * @param files packed file list
255 * @return packaging result, with the package saved as the file specified in path
256 */
257 virtual int32_t CreatePackage(const std::string &path, const std::string &keyName, PkgInfoPtr header,
258 std::vector<std::pair<std::string, ZipFileInfo>> &files) = 0;
259 virtual int32_t CreatePackage(const std::string &path, const std::string &keyName, PkgInfoPtr header,
260 std::vector<std::pair<std::string, ComponentInfo>> &files) = 0;
261 virtual int32_t CreatePackage(const std::string &path, const std::string &keyName, PkgInfoPtr header,
262 std::vector<std::pair<std::string, Lz4FileInfo>> &files) = 0;
263
264 /**
265 * Verify the signature of the upgrade package.
266 *
267 * @param packagePath file name of the update package
268 * @param keyPath file name of the key used for verification
269 * @param version version number of the update package to download
270 * @param digest digest value
271 * @param size digest value size
272 * @return verification result
273 */
274 virtual int32_t VerifyPackage(const std::string &packagePath, const std::string &keyPath,
275 const std::string &version, const PkgBuffer &digest, VerifyCallback cb) = 0;
276
277 /**
278 * Load and parse the update package.
279 *
280 * @param packagePath file name of the update package
281 * @param fileIds returned file ID list
282 * @param middleTofile file saving mode during intermediate parsing.
283 * @return loading and parsing result
284 */
285 virtual int32_t LoadPackage(const std::string &packagePath, const std::string &keyPath,
286 std::vector<std::string> &fileIds) = 0;
287
288 virtual int32_t VerifyAccPackage(const std::string &packagePath, const std::string &keyPath) = 0;
289
290 virtual int32_t VerifyOtaPackage(const std::string &devPath, uint64_t offset, size_t size) = 0;
291
292 virtual int32_t VerifyOtaPackage(const std::string &packagePath, bool isSupportOldSig) = 0;
293
294 virtual int32_t VerifyOtaPackage(const std::string &packagePath) = 0;
295
296 virtual int32_t VerifyBinFile(const std::string &packagePath, const std::string &keyPath,
297 const std::string &version, const PkgBuffer &digest) = 0;
298
299 /**
300 * Get the information about the update package.
301 *
302 * @param packagePath file name of the update package
303 * @return information about the update package
304 */
305 virtual const PkgInfo *GetPackageInfo(const std::string &packagePath) = 0;
306
307 /**
308 * Extract files from the update package, parse the files, and verify the hash value.
309 *
310 * @param fileId File ID, which is obtained from the fileIds returned by the LoadPackage function
311 * @param output output of the extracted files
312 * @return read operation result
313 */
314 virtual int32_t ExtractFile(const std::string &fileId, StreamPtr output) = 0;
315
316 /**
317 * Obtain information about the files in the update package.
318 *
319 * @param fileId file ID
320 * @return file information
321 */
322 virtual const FileInfo *GetFileInfo(const std::string &fileId) = 0;
323
324 /**
325 * Create a a package stream to output.
326 *
327 * @param stream stream for io management
328 * @param fileName file name corresponding to the stream
329 * @param size file size
330 * @param type stream type
331 * @return creation result; false if no access permission
332 */
333 virtual int32_t CreatePkgStream(StreamPtr &stream, const std::string &fileName, size_t size,
334 int32_t type) = 0;
335
336 /**
337 * Create a package stream that can be processed while parsing.
338 *
339 * @param stream stream used for io management
340 * @param fileName file name corresponding to the stream
341 * @param processor content processor
342 * @param context context for the processor
343 * @return creation result
344 */
345 virtual int32_t CreatePkgStream(StreamPtr &stream, const std::string &fileName,
346 PkgStream::ExtractFileProcessor processor, const void *context) = 0;
347
348 /**
349 * Create a package stream that can be processed while parsing.
350 *
351 * @param stream stream used for io management
352 * @param fileName file name corresponding to the stream
353 * @param buffer buffer
354 * @return creation result
355 */
356 virtual int32_t CreatePkgStream(StreamPtr &stream, const std::string &fileName, const PkgBuffer &buffer) = 0;
357
358 /**
359 * Create a package stream that can be processed while parsing.
360 *
361 * @param stream stream used for io management
362 * @param fileName file name corresponding to the stream
363 * @param buffer ringbuffer
364 * @return creation result
365 */
366 virtual int32_t CreatePkgStream(StreamPtr &stream, const std::string &fileName,
367 uint64_t fileLen, Updater::RingBuffer *buffer) = 0;
368
369 /**
370 * Close the stream
371 *
372 * @param stream stream对象
373 */
374 virtual void ClosePkgStream(StreamPtr &stream) = 0;
375
376 virtual int32_t DecompressBuffer(FileInfoPtr info, const PkgBuffer &buffer, StreamPtr output) const = 0;
377 virtual int32_t CompressBuffer(FileInfoPtr info, const PkgBuffer &buffer, StreamPtr output) const = 0;
378
379 virtual int32_t LoadPackageWithoutUnPack(const std::string &packagePath,
380 std::vector<std::string> &fileIds) = 0;
381
382 virtual int32_t LoadPackageWithStream(const std::string &packagePath, const std::string &keyPath,
383 std::vector<std::string> &fileIds, uint8_t type, StreamPtr stream) = 0;
384
385 virtual int32_t LoadPackageWithStreamForApp(AppPkgInfo &info,
386 std::vector<std::string> &fileIds, StreamPtr stream) = 0;
387
388 virtual int32_t ParsePackage(StreamPtr stream, std::vector<std::string> &fileIds, int32_t type) = 0;
389
390 virtual void SetPkgDecodeProgress(PkgDecodeProgress decodeProgress) = 0;
391
392 virtual void PostDecodeProgress(int type, size_t writeDataLen, const void *context) = 0;
393
394 virtual StreamPtr GetPkgFileStream(const std::string &fileName) = 0;
395
396 virtual int32_t ParseComponents(const std::string &packagePath, std::vector<std::string> &fileName) = 0;
397
398 /**
399 * Load and parse the update package.
400 *
401 * @param packagePath file name of the update package
402 * @param fileIds returned file ID list
403 * @param middleTofile file saving mode during intermediate parsing.
404 * @return loading and parsing result
405 */
406 virtual int32_t LoadPackage(const std::string &packagePath,
407 std::vector<std::string> &fileIds, PkgFile::PkgType type) = 0;
408 };
409
410 template <typename FileClassName>
NewPkgFile(PkgManager::PkgManagerPtr manager,PkgStreamPtr stream,PkgInfoPtr header)411 PkgFilePtr NewPkgFile(PkgManager::PkgManagerPtr manager, PkgStreamPtr stream, PkgInfoPtr header)
412 {
413 return new FileClassName (manager, stream, header);
414 }
415 } // namespace Hpackage
416 #endif // PKG_MANAGER_H
417