• 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 "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