| #pragma once | 
 |  | 
 | #include <ipmid/types.hpp> | 
 | #include <sdbusplus/server.hpp> | 
 |  | 
 | #include <chrono> | 
 | #include <cstdint> | 
 | #include <iomanip> | 
 | #include <iostream> | 
 | #include <sstream> | 
 |  | 
 | namespace ipmi | 
 | { | 
 |  | 
 | namespace sel | 
 | { | 
 |  | 
 | static constexpr auto mapperBusName = "xyz.openbmc_project.ObjectMapper"; | 
 | static constexpr auto mapperObjPath = "/xyz/openbmc_project/object_mapper"; | 
 | static constexpr auto mapperIntf = "xyz.openbmc_project.ObjectMapper"; | 
 |  | 
 | static constexpr auto logWatchPath = "/xyz/openbmc_project/logging"; | 
 | static constexpr auto logBasePath = "/xyz/openbmc_project/logging/entry"; | 
 | static constexpr auto logEntryIntf = "xyz.openbmc_project.Logging.Entry"; | 
 | static constexpr auto logDeleteIntf = "xyz.openbmc_project.Object.Delete"; | 
 |  | 
 | static constexpr auto logObj = "/xyz/openbmc_project/logging"; | 
 | static constexpr auto logIntf = "xyz.openbmc_project.Collection.DeleteAll"; | 
 | static constexpr auto logDeleteAllMethod = "DeleteAll"; | 
 |  | 
 | static constexpr auto propIntf = "org.freedesktop.DBus.Properties"; | 
 |  | 
 | using ObjectPaths = std::vector<std::string>; | 
 | using PropertyName = std::string; | 
 | using Resolved = bool; | 
 | using Id = uint32_t; | 
 | using Timestamp = uint64_t; | 
 | using Message = std::string; | 
 | using AdditionalData = std::map<std::string, std::string>; | 
 | using PropertyType = | 
 |     std::variant<Resolved, Id, Timestamp, Message, AdditionalData>; | 
 |  | 
 | static constexpr auto selVersion = 0x51; | 
 | static constexpr auto invalidTimeStamp = 0xFFFFFFFF; | 
 |  | 
 | static constexpr auto firstEntry = 0x0000; | 
 | static constexpr auto lastEntry = 0xFFFF; | 
 | static constexpr auto entireRecord = 0xFF; | 
 | static constexpr auto selRecordSize = 16; | 
 |  | 
 | namespace operationSupport | 
 | { | 
 | static constexpr bool overflow = false; | 
 | static constexpr bool deleteSel = true; | 
 | static constexpr bool partialAddSelEntry = false; | 
 | static constexpr bool reserveSel = true; | 
 | static constexpr bool getSelAllocationInfo = false; | 
 | } // namespace operationSupport | 
 |  | 
 | constexpr size_t SELRecordLength = 16; | 
 |  | 
 | /** @struct SELEventRecord | 
 |  * | 
 |  * IPMI SEL Event Record | 
 |  */ | 
 | struct SELEventRecord | 
 | { | 
 |     uint16_t recordID;        //!< Record ID. | 
 |     uint8_t recordType;       //!< Record Type. | 
 |     uint32_t timeStamp;       //!< Timestamp. | 
 |     uint16_t generatorID;     //!< Generator ID. | 
 |     uint8_t eventMsgRevision; //!< Event Message Revision. | 
 |     uint8_t sensorType;       //!< Sensor Type. | 
 |     uint8_t sensorNum;        //!< Sensor Number. | 
 |     uint8_t eventType;        //!< Event Dir | Event Type. | 
 |     uint8_t eventData1;       //!< Event Data 1. | 
 |     uint8_t eventData2;       //!< Event Data 2. | 
 |     uint8_t eventData3;       //!< Event Data 3. | 
 | } __attribute__((packed)); | 
 |  | 
 | static_assert(sizeof(SELEventRecord) == SELRecordLength); | 
 |  | 
 | /** @struct SELOEMRecordTypeCD | 
 |  * | 
 |  * IPMI SEL OEM Record - Type C0h-DFh | 
 |  */ | 
 | struct SELOEMRecordTypeCD | 
 | { | 
 |     uint16_t recordID;         //!< Record ID. | 
 |     uint8_t recordType;        //!< Record Type. | 
 |     uint32_t timeStamp;        //!< Timestamp. | 
 |     uint8_t manufacturerID[3]; //!< Manufacturer ID. | 
 |     uint8_t oemDefined[6];     //!< OEM Defined data. | 
 | } __attribute__((packed)); | 
 |  | 
 | static_assert(sizeof(SELOEMRecordTypeCD) == SELRecordLength); | 
 |  | 
 | /** @struct SELOEMRecordTypeEF | 
 |  * | 
 |  * IPMI SEL OEM Record - Type E0h-FFh | 
 |  */ | 
 | struct SELOEMRecordTypeEF | 
 | { | 
 |     uint16_t recordID;      //!< Record ID. | 
 |     uint8_t recordType;     //!< Record Type. | 
 |     uint8_t oemDefined[13]; //!< OEM Defined data. | 
 | } __attribute__((packed)); | 
 |  | 
 | static_assert(sizeof(SELOEMRecordTypeEF) == SELRecordLength); | 
 |  | 
 | union SELEventRecordFormat | 
 | { | 
 |     SELEventRecord eventRecord; | 
 |     SELOEMRecordTypeCD oemCD; | 
 |     SELOEMRecordTypeEF oemEF; | 
 | }; | 
 |  | 
 | /** @struct GetSELEntryResponse | 
 |  * | 
 |  *  IPMI payload for Get SEL Entry command response. | 
 |  */ | 
 | struct GetSELEntryResponse | 
 | { | 
 |     uint16_t nextRecordID;      //!< Next RecordID. | 
 |     SELEventRecordFormat event; // !< The Event Record. | 
 | } __attribute__((packed)); | 
 |  | 
 | static_assert(sizeof(GetSELEntryResponse) == | 
 |               SELRecordLength + sizeof(uint16_t)); | 
 |  | 
 | static constexpr auto initiateErase = 0xAA; | 
 | static constexpr auto getEraseStatus = 0x00; | 
 | static constexpr auto eraseComplete = 0x01; | 
 |  | 
 | /** @brief Convert logging entry to SEL | 
 |  * | 
 |  *  @param[in] objPath - DBUS object path of the logging entry. | 
 |  * | 
 |  *  @return On success return the response of Get SEL entry command. | 
 |  */ | 
 | GetSELEntryResponse convertLogEntrytoSEL(const std::string& objPath); | 
 |  | 
 | /** @brief Get the timestamp of the log entry | 
 |  * | 
 |  *  @param[in] objPath - DBUS object path of the logging entry. | 
 |  * | 
 |  *  @return On success return the timestamp of the log entry as number of | 
 |  *          seconds from epoch. | 
 |  */ | 
 | std::chrono::seconds getEntryTimeStamp(const std::string& objPath); | 
 |  | 
 | /** @brief Read the logging entry object paths | 
 |  * | 
 |  *  This API would read the logging dbus logging entry object paths and sorting | 
 |  *  the filename in the numeric order. The paths is cleared before populating | 
 |  *  the object paths. | 
 |  * | 
 |  *  @param[in,out] paths - sorted list of logging entry object paths. | 
 |  * | 
 |  *  @note This function is invoked when the Get SEL Info command or the Delete | 
 |  *        SEL entry command is invoked. The Get SEL Entry command is preceded | 
 |  *        typically by Get SEL Info command, so readLoggingObjectPaths is not | 
 |  *        invoked before each Get SEL entry command. | 
 |  */ | 
 | void readLoggingObjectPaths(ObjectPaths& paths); | 
 |  | 
 | template <typename T> | 
 | std::string toHexStr(const T& data) | 
 | { | 
 |     std::stringstream stream; | 
 |     stream << std::hex << std::uppercase << std::setfill('0'); | 
 |     for (const auto& v : data) | 
 |     { | 
 |         stream << std::setw(2) << static_cast<int>(v); | 
 |     } | 
 |     return stream.str(); | 
 | } | 
 | namespace internal | 
 | { | 
 |  | 
 | /** @brief Convert logging entry to SEL event record | 
 |  * | 
 |  *  @param[in] objPath - DBUS object path of the logging entry. | 
 |  *  @param[in] iter - Iterator to the sensor data corresponding to the logging | 
 |  *                    entry | 
 |  * | 
 |  *  @return On success return the SEL event record, throw an exception in case | 
 |  *          of failure. | 
 |  */ | 
 | GetSELEntryResponse prepareSELEntry( | 
 |     const std::string& objPath, | 
 |     ipmi::sensor::InvObjectIDMap::const_iterator iter); | 
 |  | 
 | } // namespace internal | 
 |  | 
 | } // namespace sel | 
 |  | 
 | } // namespace ipmi |