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), pkgVersion(pkgVersion), 51 componentBitmapBitLength(componentBitmapBitLength) 52 {} 53 54 /** @brief Parse the firmware update package header 55 * 56 * @param[in] pkgHdr - Package header 57 * @param[in] pkgSize - Size of the firmware update package 58 * 59 * @note Throws exception is parsing fails 60 */ 61 virtual void parse(const std::vector<uint8_t>& pkgHdr, 62 uintmax_t pkgSize) = 0; 63 64 /** @brief Get firmware device ID records from the package 65 * 66 * @return if parsing the package is successful, return firmware device ID 67 * records 68 */ 69 const FirmwareDeviceIDRecords& getFwDeviceIDRecords() const 70 { 71 return fwDeviceIDRecords; 72 } 73 74 /** @brief Get component image information from the package 75 * 76 * @return if parsing the package is successful, return component image 77 * information 78 */ 79 const ComponentImageInfos& getComponentImageInfos() const 80 { 81 return componentImageInfos; 82 } 83 84 /** @brief Device identifiers of the managed FDs */ 85 const PackageHeaderSize pkgHeaderSize; 86 87 /** @brief Package version string */ 88 const PackageVersion pkgVersion; 89 90 protected: 91 /** @brief Parse the firmware device identification area 92 * 93 * @param[in] deviceIdRecCount - count of firmware device ID records 94 * @param[in] pkgHdr - firmware package header 95 * @param[in] offset - offset in package header which is the start of the 96 * firmware device identification area 97 * 98 * @return On success return the offset which is the end of the firmware 99 * device identification area, on error throw exception. 100 */ 101 size_t parseFDIdentificationArea(DeviceIDRecordCount deviceIdRecCount, 102 const std::vector<uint8_t>& pkgHdr, 103 size_t offset); 104 105 /** @brief Parse the component image information area 106 * 107 * @param[in] compImageCount - component image count 108 * @param[in] pkgHdr - firmware package header 109 * @param[in] offset - offset in package header which is the start of the 110 * component image information area 111 * 112 * @return On success return the offset which is the end of the component 113 * image information area, on error throw exception. 114 */ 115 size_t parseCompImageInfoArea(ComponentImageCount compImageCount, 116 const std::vector<uint8_t>& pkgHdr, 117 size_t offset); 118 119 /** @brief Validate the total size of the package 120 * 121 * Verify the total size of the package is the sum of package header and 122 * the size of each component. 123 * 124 * @param[in] pkgSize - firmware update package size 125 * 126 * @note Throws exception if validation fails 127 */ 128 void validatePkgTotalSize(uintmax_t pkgSize); 129 130 /** @brief Firmware Device ID Records in the package */ 131 FirmwareDeviceIDRecords fwDeviceIDRecords; 132 133 /** @brief Component Image Information in the package */ 134 ComponentImageInfos componentImageInfos; 135 136 /** @brief The number of bits that will be used to represent the bitmap in 137 * the ApplicableComponents field for matching device. The value 138 * shall be a multiple of 8 and be large enough to contain a bit 139 * for each component in the package. 140 */ 141 const ComponentBitmapBitLength componentBitmapBitLength; 142 }; 143 144 /** @class PackageParserV1 145 * 146 * This class implements the package parser for the header format version 0x01 147 */ 148 class PackageParserV1 final : public PackageParser 149 { 150 public: 151 PackageParserV1() = delete; 152 PackageParserV1(const PackageParserV1&) = delete; 153 PackageParserV1(PackageParserV1&&) = default; 154 PackageParserV1& operator=(const PackageParserV1&) = delete; 155 PackageParserV1& operator=(PackageParserV1&&) = delete; 156 ~PackageParserV1() = default; 157 158 /** @brief Constructor 159 * 160 * @param[in] pkgHeaderSize - Size of package header section 161 * @param[in] pkgVersion - Package version 162 * @param[in] componentBitmapBitLength - The number of bits used to 163 * represent the bitmap in the 164 * ApplicableComponents field for a 165 * matching device. 166 */ 167 explicit PackageParserV1( 168 PackageHeaderSize pkgHeaderSize, const PackageVersion& pkgVersion, 169 ComponentBitmapBitLength componentBitmapBitLength) : 170 PackageParser(pkgHeaderSize, pkgVersion, componentBitmapBitLength) 171 {} 172 173 virtual void parse(const std::vector<uint8_t>& pkgHdr, uintmax_t pkgSize); 174 }; 175 176 /** @brief Parse the package header information 177 * 178 * @param[in] pkgHdrInfo - package header information section in the package 179 * 180 * @return On success return the PackageParser for the header format version 181 * on failure return nullptr 182 */ 183 std::unique_ptr<PackageParser> parsePkgHeader(std::vector<uint8_t>& pkgHdrInfo); 184 185 } // namespace fw_update 186 187 } // namespace pldm 188