xref: /openbmc/pldm/fw-update/package_parser.hpp (revision 16c2a0a03e5daac77e204eb99e00711490fb6e26)
11630f399STom Joseph #pragma once
21630f399STom Joseph 
31630f399STom Joseph #include "common/types.hpp"
41630f399STom Joseph 
5c453e164SGeorge Liu #include <libpldm/firmware_update.h>
6c453e164SGeorge Liu 
71630f399STom Joseph #include <array>
81630f399STom Joseph #include <cstdint>
91630f399STom Joseph #include <memory>
101630f399STom Joseph #include <tuple>
111630f399STom Joseph #include <vector>
121630f399STom Joseph 
131630f399STom Joseph namespace pldm
141630f399STom Joseph {
151630f399STom Joseph 
161630f399STom Joseph namespace fw_update
171630f399STom Joseph {
181630f399STom Joseph 
191630f399STom Joseph /** @class PackageParser
201630f399STom Joseph  *
211630f399STom Joseph  *  PackageParser is the abstract base class for parsing the PLDM firmware
221630f399STom Joseph  *  update package. The PLDM firmware update contains two major sections; the
231630f399STom Joseph  *  firmware package header, and the firmware package payload. Each package
241630f399STom Joseph  *  header version will have a concrete implementation of the PackageParser.
251630f399STom Joseph  *  The concrete implementation understands the format of the package header and
261630f399STom Joseph  *  will implement the parse API.
271630f399STom Joseph  */
281630f399STom Joseph class PackageParser
291630f399STom Joseph {
301630f399STom Joseph   public:
311630f399STom Joseph     PackageParser() = delete;
321630f399STom Joseph     PackageParser(const PackageParser&) = delete;
331630f399STom Joseph     PackageParser(PackageParser&&) = default;
341630f399STom Joseph     PackageParser& operator=(const PackageParser&) = delete;
35a7dbca53SPavithra Barithaya     PackageParser& operator=(PackageParser&&) = delete;
361630f399STom Joseph     virtual ~PackageParser() = default;
371630f399STom Joseph 
381630f399STom Joseph     /** @brief Constructor
391630f399STom Joseph      *
401630f399STom Joseph      *  @param[in] pkgHeaderSize - Size of package header section
411630f399STom Joseph      *  @param[in] pkgVersion - Package version
421630f399STom Joseph      *  @param[in] componentBitmapBitLength - The number of bits used to
431630f399STom Joseph      *                                        represent the bitmap in the
441630f399STom Joseph      *                                        ApplicableComponents field for a
451630f399STom Joseph      *                                        matching device.
461630f399STom Joseph      */
PackageParser(PackageHeaderSize pkgHeaderSize,const PackageVersion & pkgVersion,ComponentBitmapBitLength componentBitmapBitLength)471630f399STom Joseph     explicit PackageParser(PackageHeaderSize pkgHeaderSize,
481630f399STom Joseph                            const PackageVersion& pkgVersion,
491630f399STom Joseph                            ComponentBitmapBitLength componentBitmapBitLength) :
50*16c2a0a0SPatrick Williams         pkgHeaderSize(pkgHeaderSize), pkgVersion(pkgVersion),
511630f399STom Joseph         componentBitmapBitLength(componentBitmapBitLength)
521630f399STom Joseph     {}
531630f399STom Joseph 
541630f399STom Joseph     /** @brief Parse the firmware update package header
551630f399STom Joseph      *
561630f399STom Joseph      *  @param[in] pkgHdr - Package header
571630f399STom Joseph      *  @param[in] pkgSize - Size of the firmware update package
581630f399STom Joseph      *
591630f399STom Joseph      *  @note Throws exception is parsing fails
601630f399STom Joseph      */
611630f399STom Joseph     virtual void parse(const std::vector<uint8_t>& pkgHdr,
621630f399STom Joseph                        uintmax_t pkgSize) = 0;
631630f399STom Joseph 
641630f399STom Joseph     /** @brief Get firmware device ID records from the package
651630f399STom Joseph      *
661630f399STom Joseph      *  @return if parsing the package is successful, return firmware device ID
671630f399STom Joseph      *          records
681630f399STom Joseph      */
getFwDeviceIDRecords() const691630f399STom Joseph     const FirmwareDeviceIDRecords& getFwDeviceIDRecords() const
701630f399STom Joseph     {
711630f399STom Joseph         return fwDeviceIDRecords;
721630f399STom Joseph     }
731630f399STom Joseph 
741630f399STom Joseph     /** @brief Get component image information from the package
751630f399STom Joseph      *
761630f399STom Joseph      *  @return if parsing the package is successful, return component image
771630f399STom Joseph      *          information
781630f399STom Joseph      */
getComponentImageInfos() const791630f399STom Joseph     const ComponentImageInfos& getComponentImageInfos() const
801630f399STom Joseph     {
811630f399STom Joseph         return componentImageInfos;
821630f399STom Joseph     }
831630f399STom Joseph 
841630f399STom Joseph     /** @brief Device identifiers of the managed FDs */
851630f399STom Joseph     const PackageHeaderSize pkgHeaderSize;
861630f399STom Joseph 
871630f399STom Joseph     /** @brief Package version string */
881630f399STom Joseph     const PackageVersion pkgVersion;
891630f399STom Joseph 
901630f399STom Joseph   protected:
911630f399STom Joseph     /** @brief Parse the firmware device identification area
921630f399STom Joseph      *
931630f399STom Joseph      *  @param[in] deviceIdRecCount - count of firmware device ID records
941630f399STom Joseph      *  @param[in] pkgHdr - firmware package header
951630f399STom Joseph      *  @param[in] offset - offset in package header which is the start of the
961630f399STom Joseph      *                      firmware device identification area
971630f399STom Joseph      *
981630f399STom Joseph      *  @return On success return the offset which is the end of the firmware
991630f399STom Joseph      *          device identification area, on error throw exception.
1001630f399STom Joseph      */
1011630f399STom Joseph     size_t parseFDIdentificationArea(DeviceIDRecordCount deviceIdRecCount,
1021630f399STom Joseph                                      const std::vector<uint8_t>& pkgHdr,
1031630f399STom Joseph                                      size_t offset);
1041630f399STom Joseph 
1051630f399STom Joseph     /** @brief Parse the component image information area
1061630f399STom Joseph      *
1071630f399STom Joseph      *  @param[in] compImageCount - component image count
1081630f399STom Joseph      *  @param[in] pkgHdr - firmware package header
1091630f399STom Joseph      *  @param[in] offset - offset in package header which is the start of the
1101630f399STom Joseph      *                      component image information area
1111630f399STom Joseph      *
1121630f399STom Joseph      *  @return On success return the offset which is the end of the component
1131630f399STom Joseph      *          image information area, on error throw exception.
1141630f399STom Joseph      */
1151630f399STom Joseph     size_t parseCompImageInfoArea(ComponentImageCount compImageCount,
1161630f399STom Joseph                                   const std::vector<uint8_t>& pkgHdr,
1171630f399STom Joseph                                   size_t offset);
1181630f399STom Joseph 
1191630f399STom Joseph     /** @brief Validate the total size of the package
1201630f399STom Joseph      *
1211630f399STom Joseph      *  Verify the total size of the package is the sum of package header and
1221630f399STom Joseph      *  the size of each component.
1231630f399STom Joseph      *
1241630f399STom Joseph      *  @param[in] pkgSize - firmware update package size
1251630f399STom Joseph      *
1261630f399STom Joseph      *  @note Throws exception if validation fails
1271630f399STom Joseph      */
1281630f399STom Joseph     void validatePkgTotalSize(uintmax_t pkgSize);
1291630f399STom Joseph 
1301630f399STom Joseph     /** @brief Firmware Device ID Records in the package */
1311630f399STom Joseph     FirmwareDeviceIDRecords fwDeviceIDRecords;
1321630f399STom Joseph 
1331630f399STom Joseph     /** @brief Component Image Information in the package */
1341630f399STom Joseph     ComponentImageInfos componentImageInfos;
1351630f399STom Joseph 
1361630f399STom Joseph     /** @brief The number of bits that will be used to represent the bitmap in
1371630f399STom Joseph      *         the ApplicableComponents field for matching device. The value
1381630f399STom Joseph      *         shall be a multiple of 8 and be large enough to contain a bit
1391630f399STom Joseph      *         for each component in the package.
1401630f399STom Joseph      */
1411630f399STom Joseph     const ComponentBitmapBitLength componentBitmapBitLength;
1421630f399STom Joseph };
1431630f399STom Joseph 
1441630f399STom Joseph /** @class PackageParserV1
1451630f399STom Joseph  *
1461630f399STom Joseph  *  This class implements the package parser for the header format version 0x01
1471630f399STom Joseph  */
1481630f399STom Joseph class PackageParserV1 final : public PackageParser
1491630f399STom Joseph {
1501630f399STom Joseph   public:
1511630f399STom Joseph     PackageParserV1() = delete;
1521630f399STom Joseph     PackageParserV1(const PackageParserV1&) = delete;
1531630f399STom Joseph     PackageParserV1(PackageParserV1&&) = default;
1541630f399STom Joseph     PackageParserV1& operator=(const PackageParserV1&) = delete;
155a7dbca53SPavithra Barithaya     PackageParserV1& operator=(PackageParserV1&&) = delete;
1561630f399STom Joseph     ~PackageParserV1() = default;
1571630f399STom Joseph 
1581630f399STom Joseph     /** @brief Constructor
1591630f399STom Joseph      *
1601630f399STom Joseph      *  @param[in] pkgHeaderSize - Size of package header section
1611630f399STom Joseph      *  @param[in] pkgVersion - Package version
1621630f399STom Joseph      *  @param[in] componentBitmapBitLength - The number of bits used to
1631630f399STom Joseph      *                                        represent the bitmap in the
1641630f399STom Joseph      *                                        ApplicableComponents field for a
1651630f399STom Joseph      *                                        matching device.
1661630f399STom Joseph      */
PackageParserV1(PackageHeaderSize pkgHeaderSize,const PackageVersion & pkgVersion,ComponentBitmapBitLength componentBitmapBitLength)1671630f399STom Joseph     explicit PackageParserV1(
1681630f399STom Joseph         PackageHeaderSize pkgHeaderSize, const PackageVersion& pkgVersion,
1691630f399STom Joseph         ComponentBitmapBitLength componentBitmapBitLength) :
1701630f399STom Joseph         PackageParser(pkgHeaderSize, pkgVersion, componentBitmapBitLength)
1711630f399STom Joseph     {}
1721630f399STom Joseph 
1731630f399STom Joseph     virtual void parse(const std::vector<uint8_t>& pkgHdr, uintmax_t pkgSize);
1741630f399STom Joseph };
1751630f399STom Joseph 
1761630f399STom Joseph /** @brief Parse the package header information
1771630f399STom Joseph  *
1781630f399STom Joseph  *  @param[in] pkgHdrInfo - package header information section in the package
1791630f399STom Joseph  *
1801630f399STom Joseph  *  @return On success return the PackageParser for the header format version
1811630f399STom Joseph  *          on failure return nullptr
1821630f399STom Joseph  */
1831630f399STom Joseph std::unique_ptr<PackageParser> parsePkgHeader(std::vector<uint8_t>& pkgHdrInfo);
1841630f399STom Joseph 
1851630f399STom Joseph } // namespace fw_update
1861630f399STom Joseph 
1871630f399STom Joseph } // namespace pldm
188