1 #pragma once 2 3 #include "common/types.hpp" 4 5 #include <libpldm/firmware_update.h> 6 7 #include <array> 8 #include <cstdint> 9 #include <memory> 10 #include <tuple> 11 #include <vector> 12 13 namespace pldm 14 { 15 16 namespace fw_update 17 { 18 19 /** @class PackageParser 20 * 21 * PackageParser is the abstract base class for parsing the PLDM firmware 22 * update package. The PLDM firmware update contains two major sections; the 23 * firmware package header, and the firmware package payload. Each package 24 * header version will have a concrete implementation of the PackageParser. 25 * The concrete implementation understands the format of the package header and 26 * will implement the parse API. 27 */ 28 class PackageParser 29 { 30 public: 31 PackageParser() = delete; 32 PackageParser(const PackageParser&) = delete; 33 PackageParser(PackageParser&&) = default; 34 PackageParser& operator=(const PackageParser&) = delete; 35 PackageParser& operator=(PackageParser&&) = delete; 36 virtual ~PackageParser() = default; 37 38 /** @brief Constructor 39 * 40 * @param[in] pkgHeaderSize - Size of package header section 41 * @param[in] pkgVersion - Package version 42 * @param[in] componentBitmapBitLength - The number of bits used to 43 * represent the bitmap in the 44 * ApplicableComponents field for a 45 * matching device. 46 */ 47 explicit PackageParser(PackageHeaderSize pkgHeaderSize, 48 const PackageVersion& pkgVersion, 49 ComponentBitmapBitLength componentBitmapBitLength) : 50 pkgHeaderSize(pkgHeaderSize), 51 pkgVersion(pkgVersion), 52 componentBitmapBitLength(componentBitmapBitLength) 53 {} 54 55 /** @brief Parse the firmware update package header 56 * 57 * @param[in] pkgHdr - Package header 58 * @param[in] pkgSize - Size of the firmware update package 59 * 60 * @note Throws exception is parsing fails 61 */ 62 virtual void parse(const std::vector<uint8_t>& pkgHdr, 63 uintmax_t pkgSize) = 0; 64 65 /** @brief Get firmware device ID records from the package 66 * 67 * @return if parsing the package is successful, return firmware device ID 68 * records 69 */ 70 const FirmwareDeviceIDRecords& getFwDeviceIDRecords() const 71 { 72 return fwDeviceIDRecords; 73 } 74 75 /** @brief Get component image information from the package 76 * 77 * @return if parsing the package is successful, return component image 78 * information 79 */ 80 const ComponentImageInfos& getComponentImageInfos() const 81 { 82 return componentImageInfos; 83 } 84 85 /** @brief Device identifiers of the managed FDs */ 86 const PackageHeaderSize pkgHeaderSize; 87 88 /** @brief Package version string */ 89 const PackageVersion pkgVersion; 90 91 protected: 92 /** @brief Parse the firmware device identification area 93 * 94 * @param[in] deviceIdRecCount - count of firmware device ID records 95 * @param[in] pkgHdr - firmware package header 96 * @param[in] offset - offset in package header which is the start of the 97 * firmware device identification area 98 * 99 * @return On success return the offset which is the end of the firmware 100 * device identification area, on error throw exception. 101 */ 102 size_t parseFDIdentificationArea(DeviceIDRecordCount deviceIdRecCount, 103 const std::vector<uint8_t>& pkgHdr, 104 size_t offset); 105 106 /** @brief Parse the component image information area 107 * 108 * @param[in] compImageCount - component image count 109 * @param[in] pkgHdr - firmware package header 110 * @param[in] offset - offset in package header which is the start of the 111 * component image information area 112 * 113 * @return On success return the offset which is the end of the component 114 * image information area, on error throw exception. 115 */ 116 size_t parseCompImageInfoArea(ComponentImageCount compImageCount, 117 const std::vector<uint8_t>& pkgHdr, 118 size_t offset); 119 120 /** @brief Validate the total size of the package 121 * 122 * Verify the total size of the package is the sum of package header and 123 * the size of each component. 124 * 125 * @param[in] pkgSize - firmware update package size 126 * 127 * @note Throws exception if validation fails 128 */ 129 void validatePkgTotalSize(uintmax_t pkgSize); 130 131 /** @brief Firmware Device ID Records in the package */ 132 FirmwareDeviceIDRecords fwDeviceIDRecords; 133 134 /** @brief Component Image Information in the package */ 135 ComponentImageInfos componentImageInfos; 136 137 /** @brief The number of bits that will be used to represent the bitmap in 138 * the ApplicableComponents field for matching device. The value 139 * shall be a multiple of 8 and be large enough to contain a bit 140 * for each component in the package. 141 */ 142 const ComponentBitmapBitLength componentBitmapBitLength; 143 }; 144 145 /** @class PackageParserV1 146 * 147 * This class implements the package parser for the header format version 0x01 148 */ 149 class PackageParserV1 final : public PackageParser 150 { 151 public: 152 PackageParserV1() = delete; 153 PackageParserV1(const PackageParserV1&) = delete; 154 PackageParserV1(PackageParserV1&&) = default; 155 PackageParserV1& operator=(const PackageParserV1&) = delete; 156 PackageParserV1& operator=(PackageParserV1&&) = delete; 157 ~PackageParserV1() = default; 158 159 /** @brief Constructor 160 * 161 * @param[in] pkgHeaderSize - Size of package header section 162 * @param[in] pkgVersion - Package version 163 * @param[in] componentBitmapBitLength - The number of bits used to 164 * represent the bitmap in the 165 * ApplicableComponents field for a 166 * matching device. 167 */ 168 explicit PackageParserV1( 169 PackageHeaderSize pkgHeaderSize, const PackageVersion& pkgVersion, 170 ComponentBitmapBitLength componentBitmapBitLength) : 171 PackageParser(pkgHeaderSize, pkgVersion, componentBitmapBitLength) 172 {} 173 174 virtual void parse(const std::vector<uint8_t>& pkgHdr, uintmax_t pkgSize); 175 }; 176 177 /** @brief Parse the package header information 178 * 179 * @param[in] pkgHdrInfo - package header information section in the package 180 * 181 * @return On success return the PackageParser for the header format version 182 * on failure return nullptr 183 */ 184 std::unique_ptr<PackageParser> parsePkgHeader(std::vector<uint8_t>& pkgHdrInfo); 185 186 } // namespace fw_update 187 188 } // namespace pldm 189