| #pragma once | 
 |  | 
 | #include "host_interface.hpp" | 
 |  | 
 | #include <libpldm/instance-id.h> | 
 | #include <libpldm/pldm.h> | 
 | #include <libpldm/transport.h> | 
 | #include <libpldm/transport/mctp-demux.h> | 
 |  | 
 | #include <sdeventplus/clock.hpp> | 
 | #include <sdeventplus/source/io.hpp> | 
 | #include <sdeventplus/utility/timer.hpp> | 
 |  | 
 | #include <chrono> | 
 | #include <memory> | 
 |  | 
 | namespace openpower::pels | 
 | { | 
 |  | 
 | /** | 
 |  * @class PLDMInterface | 
 |  * | 
 |  * This class handles sending the 'new file available' PLDM | 
 |  * command to the host to notify it of a new PEL's ID and size. | 
 |  * | 
 |  * The command response is asynchronous. | 
 |  */ | 
 | class PLDMInterface : public HostInterface | 
 | { | 
 |   public: | 
 |     PLDMInterface() = delete; | 
 |     PLDMInterface(const PLDMInterface&) = delete; | 
 |     PLDMInterface& operator=(const PLDMInterface&) = delete; | 
 |     PLDMInterface(PLDMInterface&&) = delete; | 
 |     PLDMInterface& operator=(PLDMInterface&&) = delete; | 
 |  | 
 |     /** | 
 |      * @brief Constructor | 
 |      * | 
 |      * @param[in] event - The sd_event object pointer | 
 |      * @param[in] dataIface - The DataInterface object | 
 |      */ | 
 |     PLDMInterface(sd_event* event, DataInterfaceBase& dataIface) : | 
 |         HostInterface(event, dataIface), | 
 |         _receiveTimer( | 
 |             event, | 
 |             std::bind(std::mem_fn(&PLDMInterface::receiveTimerExpired), this)) | 
 |     { | 
 |         pldm_instance_db_init_default(&_pldm_idb); | 
 |  | 
 |         readEID(); | 
 |     } | 
 |  | 
 |     /** | 
 |      * @brief Destructor | 
 |      */ | 
 |     ~PLDMInterface() override; | 
 |  | 
 |     /** | 
 |      * @brief Kicks off the send of the 'new file available' command | 
 |      *        to send up the ID and size of the new PEL. | 
 |      * | 
 |      * It starts by issuing the async D-Bus method call to read the | 
 |      * instance ID. | 
 |      * | 
 |      * @param[in] id - The PEL ID | 
 |      * @param[in] size - The PEL size in bytes | 
 |      * | 
 |      * @return CmdStatus - the success/fail status of the send | 
 |      */ | 
 |     CmdStatus sendNewLogCmd(uint32_t id, uint32_t size) override; | 
 |  | 
 |     /** | 
 |      * @brief Cancels waiting for a command response | 
 |      * | 
 |      * This will clear the instance ID so the next command | 
 |      * will request a new one. | 
 |      */ | 
 |     void cancelCmd() override; | 
 |  | 
 |     /** | 
 |      * @brief Cleans up so that a new command is ready to be sent. | 
 |      * | 
 |      * Does not clear the instance ID. | 
 |      */ | 
 |     void cleanupCmd(); | 
 |  | 
 |   private: | 
 |     /** | 
 |      * @brief The asynchronous callback for getting the response | 
 |      *        of the 'new file available' command. | 
 |      * | 
 |      * Calls the response callback that is registered. | 
 |      * | 
 |      * @param[in] io - The event source object | 
 |      * @param[in] fd - The FD used | 
 |      * @param[in] revents - The event bits | 
 |      * @param[in] transport - The transport data pointer | 
 |      */ | 
 |     void receive(sdeventplus::source::IO& io, int fd, uint32_t revents, | 
 |                  pldm_transport* transport) override; | 
 |  | 
 |     /** | 
 |      * @brief Function called when the receive timer expires. | 
 |      * | 
 |      * This is considered a failure and so will invoke the | 
 |      * registered response callback function with a failure | 
 |      * indication. | 
 |      */ | 
 |     void receiveTimerExpired(); | 
 |  | 
 |     /** | 
 |      * @brief Configures the sdeventplus::source::IO object to | 
 |      *        call receive() on EPOLLIN activity on the PLDM FD | 
 |      *        which is used for command responses. | 
 |      */ | 
 |     void registerReceiveCallback(); | 
 |  | 
 |     /** | 
 |      * @brief Reads the MCTP endpoint ID out of a file | 
 |      */ | 
 |     void readEID(); | 
 |  | 
 |     /** | 
 |      * @brief Opens the PLDM file descriptor | 
 |      */ | 
 |     void open(); | 
 |  | 
 |     /** @brief Opens the MCTP socket for sending and receiving messages. | 
 |      * | 
 |      */ | 
 |     int openMctpDemuxTransport(); | 
 |  | 
 |     /** | 
 |      * @brief Encodes and sends the PLDM 'new file available' cmd | 
 |      */ | 
 |     void doSend(); | 
 |  | 
 |     /** | 
 |      * @brief Closes the PLDM file descriptor | 
 |      */ | 
 |     void closeFD(); | 
 |  | 
 |     /** | 
 |      * @brief Kicks off the send of the 'new file available' command | 
 |      *        to send the ID and size of a PEL after the instance ID | 
 |      *        has been retrieved. | 
 |      */ | 
 |     void startCommand(); | 
 |  | 
 |     /** | 
 |      * @brief Allocates the instance id. | 
 |      */ | 
 |     void allocIID(); | 
 |  | 
 |     /** | 
 |      * @brief Frees the instance id. | 
 |      */ | 
 |     void freeIID(); | 
 |  | 
 |     /** | 
 |      * @brief The MCTP endpoint ID | 
 |      */ | 
 |     mctp_eid_t _eid; | 
 |  | 
 |     /** | 
 |      * @brief The PLDM instance ID of the current command | 
 |      * | 
 |      * A new ID will be used for every command. | 
 |      * | 
 |      * If there are command failures, the same instance ID can be | 
 |      * used on retries only if the host didn't respond. | 
 |      */ | 
 |     std::optional<pldm_instance_id_t> _instanceID; | 
 |  | 
 |     /** | 
 |      * @brief The PLDM command file descriptor for the current command | 
 |      */ | 
 |     int _fd = -1; | 
 |  | 
 |     /** | 
 |      * @brief The event object for handling callbacks on the PLDM FD | 
 |      */ | 
 |     std::unique_ptr<sdeventplus::source::IO> _source; | 
 |  | 
 |     /** | 
 |      * @brief A timer to only allow a certain amount of time for the | 
 |      *        async PLDM receive before it is considered a failure. | 
 |      */ | 
 |     sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> _receiveTimer; | 
 |  | 
 |     /** | 
 |      * @brief The command timeout value | 
 |      */ | 
 |     const std::chrono::milliseconds _receiveTimeout{45000}; | 
 |  | 
 |     /** | 
 |      * @brief The libpldm instance ID database. | 
 |      */ | 
 |     pldm_instance_db* _pldm_idb = nullptr; | 
 |  | 
 |     /** | 
 |      * @brief The ID of the PEL to notify the host of. | 
 |      */ | 
 |     uint32_t _pelID = 0; | 
 |  | 
 |     /** | 
 |      * @brief The size of the PEL to notify the host of. | 
 |      */ | 
 |     uint32_t _pelSize = 0; | 
 |  | 
 |     /** | 
 |      * @brief pldm transport instance. | 
 |      */ | 
 |     pldm_transport* pldmTransport = nullptr; | 
 |  | 
 |     pldm_transport_mctp_demux* mctpDemux = nullptr; | 
 |  | 
 |     /** | 
 |      * @brief The header for the most recent request. | 
 |      */ | 
 |     pldm_msg_hdr _requestHeader{}; | 
 | }; | 
 |  | 
 | } // namespace openpower::pels |