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