• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "package/package.h"
26 
27 namespace Hpackage {
28 /**
29  * Error code definition
30  */
31 enum {
32     PKG_SUCCESS = 0,
33     PKG_ERROR_BASE = 100,
34     PKG_INVALID_NAME,
35     PKG_INVALID_PARAM,
36     PKG_INVALID_FILE,
37     PKG_INVALID_SIGNATURE,
38     PKG_INVALID_PKG_FORMAT,
39     PKG_INVALID_ALGORITHM,
40     PKG_INVALID_DIGEST,
41     PKG_INVALID_STREAM,
42     PKG_INVALID_VERSION,
43     PKG_INVALID_STATE,
44     PKG_INVALID_LZ4,
45     PKG_NONE_PERMISSION,
46     PKG_NONE_MEMORY,
47     PKG_VERIFY_FAIL,
48 };
49 
50 enum {
51     POST_TYPE_UPLOAD_PKG = 0,
52     POST_TYPE_DECODE_PKG,
53     POST_TYPE_VERIFY_PKG,
54     POST_TYPE_WRITE_PARTITION
55 };
56 
57 /**
58  * Package information
59  */
60 struct PkgInfo {
61     uint32_t entryCount = 0;
62     uint8_t signMethod;
63     uint8_t digestMethod;
64     uint8_t pkgType;
65     uint8_t pkgFlags;
66 };
67 
68 /**
69  * File information
70  */
71 struct FileInfo {
72     uint8_t flags = 0;
73     uint8_t digestMethod = 0;
74     uint16_t packMethod = 0;
75     time_t modifiedTime = 0;
76     size_t packedSize = 0;
77     size_t unpackedSize = 0;
78     size_t headerOffset = 0;
79     size_t dataOffset = 0;
80     std::string identity;
81 };
82 
83 /**
84  * Header information of the update package
85  */
86 struct UpgradePkgInfo {
87     PkgInfo pkgInfo;
88     uint32_t updateFileVersion = 0;
89     std::string productUpdateId;
90     std::string softwareVersion;
91     std::string date;
92     std::string time;
93     std::string descriptPackageId;
94 };
95 
96 /**
97  * Component information of the update package
98  */
99 struct ComponentInfo {
100     FileInfo fileInfo;
101     std::string version;
102     uint8_t digest[DIGEST_MAX_LEN];
103     uint16_t id;
104     uint8_t resType;
105     uint8_t type;
106     uint8_t compFlags;
107     size_t originalSize;
108 };
109 
110 /**
111  * Lz4 file configuration information
112  */
113 struct Lz4FileInfo {
114     FileInfo fileInfo;
115     int8_t compressionLevel;
116     int8_t blockIndependence;
117     int8_t contentChecksumFlag;
118     int8_t blockSizeID;
119     int8_t autoFlush = 1;
120 };
121 
122 /**
123  * Zip file configuration information
124  */
125 struct ZipFileInfo {
126     FileInfo fileInfo;
127     int32_t method = -1; // The system automatically uses the default value if the value is -1.
128     int32_t level;
129     int32_t windowBits;
130     int32_t memLevel;
131     int32_t strategy;
132 };
133 
134 /**
135  * buff definition used for parsing
136  */
137 struct PkgBuffer {
138     uint8_t *buffer;
139     size_t length = 0; // buffer size
140     std::vector<uint8_t> data;
141 
PkgBufferPkgBuffer142     PkgBuffer()
143     {
144         this->buffer = nullptr;
145         this->length = 0;
146     }
147 
PkgBufferPkgBuffer148     PkgBuffer(uint8_t *buffer, size_t bufferSize)
149     {
150         this->buffer = buffer;
151         this->length = bufferSize;
152     }
153 
PkgBufferPkgBuffer154     PkgBuffer(std::vector<uint8_t> &buffer)
155     {
156         this->buffer = buffer.data();
157         this->length = buffer.capacity();
158     }
159 
PkgBufferPkgBuffer160     PkgBuffer(size_t bufferSize)
161     {
162         data.resize(bufferSize, 0);
163         this->buffer = data.data();
164         this->length = bufferSize;
165     }
166 };
167 
168 /**
169  * Input and output stream definition
170  */
171 class PkgStream {
172 public:
173     enum {
174         PkgStreamType_Read = 0,     // common file reading
175         PkgStreamType_Write,        // common file writing (A new file is created and the original content is deleted.)
176         PkgStreamType_MemoryMap,    // memory mapping
177         PkgStreamType_Process,      // processing while parsing
178         PkgStreamType_Buffer,       // buffer
179     };
180 
181     virtual ~PkgStream() = default;
182 
183     /**
184      * Read files.
185      *
186      * @param buff                  buffer to hold the output file content
187      * @param start                 start position of reading
188      * @param needRead              size of the data to read
189      * @param readLen               length of the read data
190      * @return                      file reading result
191      */
192     virtual int32_t Read(const PkgBuffer &data, size_t start, size_t needRead, size_t &readLen) = 0;
193 
194     virtual int32_t GetBuffer(PkgBuffer &buffer) const = 0;
195 
196     virtual size_t GetFileLength() = 0;
197     virtual const std::string GetFileName() const = 0;
198     virtual int32_t GetStreamType() const = 0;
199 
200     using ExtractFileProcessor = std::function<int(const PkgBuffer &data, size_t size, size_t start,
201         bool isFinish, const void *context)>;
202 
GetBuffer(uint8_t * & buffer,size_t & size)203     int32_t GetBuffer(uint8_t *&buffer, size_t &size)
204     {
205         PkgBuffer data = {};
206         int ret = GetBuffer(data);
207         buffer = data.buffer;
208         size = data.length;
209         return ret;
210     }
211 };
212 
213 using PkgDecodeProgress = std::function<void(int type, size_t writeDataLen, const void *context)>;
214 
215 /**
216  * Get a singleton PkgManager instance.
217  */
218 class PkgManager {
219 public:
220     using PkgManagerPtr = PkgManager *;
221     using FileInfoPtr = FileInfo *;
222     using PkgInfoPtr = PkgInfo *;
223     using StreamPtr = PkgStream *;
224     using VerifyCallback = std::function<void(int32_t result, uint32_t percent)>;
225 
226     virtual ~PkgManager() = default;
227 
228     static PkgManagerPtr CreatePackageInstance();
229     static PkgManagerPtr GetPackageInstance();
230     static void ReleasePackageInstance(PkgManagerPtr manager);
231 
232     /**
233      * Create an update package based on specified parameters.
234      *
235      * @param path              path of the update package
236      * @param header            header, which mainly consists of algorithm information
237      * @param files             packed file list
238      * @return                  packaging result, with the package saved as the file specified in path
239      */
240     virtual int32_t CreatePackage(const std::string &path, const std::string &keyName, PkgInfoPtr header,
241         std::vector<std::pair<std::string, ZipFileInfo>> &files) = 0;
242     virtual int32_t CreatePackage(const std::string &path, const std::string &keyName, PkgInfoPtr header,
243         std::vector<std::pair<std::string, ComponentInfo>> &files) = 0;
244     virtual int32_t CreatePackage(const std::string &path, const std::string &keyName, PkgInfoPtr header,
245         std::vector<std::pair<std::string, Lz4FileInfo>> &files) = 0;
246 
247     /**
248      * Verify the signature of the upgrade package.
249      *
250      * @param packagePath       file name of the update package
251      * @param keyPath           file name of the key used for verification
252      * @param version           version number of the update package to download
253      * @param digest            digest value
254      * @param size              digest value size
255      * @return                  verification result
256      */
257     virtual int32_t VerifyPackage(const std::string &packagePath, const std::string &keyPath,
258         const std::string &version, const PkgBuffer &digest, VerifyCallback cb) = 0;
259 
260     /**
261      * Load and parse the update package.
262      *
263      * @param packagePath       file name of the update package
264      * @param fileIds           returned file ID list
265      * @param middleTofile      file saving mode during intermediate parsing.
266      * @return                  loading and parsing result
267      */
268     virtual int32_t LoadPackage(const std::string &packagePath, const std::string &keyPath,
269         std::vector<std::string> &fileIds) = 0;
270 
271     virtual int32_t VerifyOtaPackage(const std::string &packagePath) = 0;
272 
273     virtual int32_t VerifyBinFile(const std::string &packagePath, const std::string &keyPath,
274         const std::string &version, const PkgBuffer &digest) = 0;
275 
276     /**
277      * Get the information about the update package.
278      *
279      * @param packagePath   file name of the update package
280      * @return              information about the update package
281      */
282     virtual const PkgInfo *GetPackageInfo(const std::string &packagePath) = 0;
283 
284     /**
285      * Extract files from the update package, parse the files, and verify the hash value.
286      *
287      * @param fileId        File ID, which is obtained from the fileIds returned by the LoadPackage function
288      * @param output        output of the extracted files
289      * @return              read operation result
290      */
291     virtual int32_t ExtractFile(const std::string &fileId, StreamPtr output) = 0;
292 
293     /**
294      * Obtain information about the files in the update package.
295      *
296      * @param fileId        file ID
297      * @return              file information
298      */
299     virtual const FileInfo *GetFileInfo(const std::string &fileId) = 0;
300 
301     /**
302      * Create a a package stream to output.
303      *
304      * @param stream        stream for io management
305      * @param fileName      file name corresponding to the stream
306      * @param size          file size
307      * @param type          stream type
308      * @return              creation result; false if no access permission
309      */
310     virtual int32_t CreatePkgStream(StreamPtr &stream, const std::string &fileName, size_t size,
311         int32_t type) = 0;
312 
313     /**
314      * Create a package stream that can be processed while parsing.
315      *
316      * @param stream        stream used for io management
317      * @param fileName      file name corresponding to the stream
318      * @param processor     content processor
319      * @param context       context for the processor
320      * @return              creation result
321      */
322     virtual int32_t CreatePkgStream(StreamPtr &stream, const std::string &fileName,
323         PkgStream::ExtractFileProcessor processor, const void *context) = 0;
324 
325     /**
326      * Create a package stream that can be processed while parsing.
327      *
328      * @param stream        stream used for io management
329      * @param fileName      file name corresponding to the stream
330      * @param buffer        buffer
331      * @return              creation result
332      */
333     virtual int32_t CreatePkgStream(StreamPtr &stream, const std::string &fileName, const PkgBuffer &buffer) = 0;
334 
335     /**
336      * Close the stream
337      *
338      * @param stream  stream对象
339      */
340     virtual void ClosePkgStream(StreamPtr &stream) = 0;
341 
342     virtual int32_t DecompressBuffer(FileInfoPtr info, const PkgBuffer &buffer, StreamPtr output) const = 0;
343     virtual int32_t CompressBuffer(FileInfoPtr info, const PkgBuffer &buffer, StreamPtr output) const = 0;
344 
345     virtual int32_t LoadPackageWithoutUnPack(const std::string &packagePath,
346         std::vector<std::string> &fileIds) = 0;
347 
348     virtual int32_t ParsePackage(StreamPtr stream, std::vector<std::string> &fileIds, int32_t type) = 0;
349 
350     virtual void SetPkgDecodeProgress(PkgDecodeProgress decodeProgress) = 0;
351 
352     virtual void PostDecodeProgress(int type, size_t writeDataLen, const void *context) = 0;
353 };
354 } // namespace Hpackage
355 #endif // PKG_MANAGER_H
356