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