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