blob: 0d679a142f2b8a1af086e2320fa8ce7ce475d056 [file] [log] [blame]
Matt Spinler5c350fd2019-12-12 13:53:53 -06001#pragma once
2
3#include "host_interface.hpp"
4
5#include <libpldm/pldm.h>
6
7#include <chrono>
8#include <memory>
9#include <sdeventplus/clock.hpp>
10#include <sdeventplus/source/io.hpp>
11#include <sdeventplus/utility/timer.hpp>
12
13namespace openpower::pels
14{
15
16/**
17 * @class PLDMInterface
18 *
19 * This class handles sending the 'new file available' PLDM
20 * command to the host to notify it of a new PEL's ID and size.
21 *
22 * The command response is asynchronous.
23 */
24class PLDMInterface : public HostInterface
25{
26 public:
27 PLDMInterface() = delete;
28 PLDMInterface(const PLDMInterface&) = default;
29 PLDMInterface& operator=(const PLDMInterface&) = default;
30 PLDMInterface(PLDMInterface&&) = default;
31 PLDMInterface& operator=(PLDMInterface&&) = default;
32
33 /**
34 * @brief Constructor
35 *
36 * @param[in] event - The sd_event object pointer
37 * @param[in] dataIface - The DataInterface object
38 */
39 PLDMInterface(sd_event* event, DataInterfaceBase& dataIface) :
40 HostInterface(event, dataIface),
41 _receiveTimer(
42 event,
43 std::bind(std::mem_fn(&PLDMInterface::receiveTimerExpired), this))
44 {
45 readEID();
46 }
47
48 /**
49 * @brief Destructor
50 */
51 ~PLDMInterface();
52
53 /**
54 * @brief Kicks off the send of the 'new file available' command
55 * to send up the ID and size of the new PEL.
56 *
57 * @param[in] id - The PEL ID
58 * @param[in] size - The PEL size in bytes
59 *
60 * @return CmdStatus - the success/fail status of the send
61 */
62 CmdStatus sendNewLogCmd(uint32_t id, uint32_t size) override;
63
64 /**
65 * @brief Cancels waiting for a command response
66 */
67 void cancelCmd() override;
68
69 private:
70 /**
71 * @brief The asynchronous callback for getting the response
72 * of the 'new file available' command.
73 *
74 * Calls the response callback that is registered.
75 *
76 * @param[in] io - The event source object
77 * @param[in] fd - The FD used
78 * @param[in] revents - The event bits
79 */
80 void receive(sdeventplus::source::IO& io, int fd,
81 uint32_t revents) override;
82
83 /**
84 * @brief Function called when the receive timer expires.
85 *
86 * This is considered a failure and so will invoke the
87 * registered response callback function with a failure
88 * indication.
89 */
90 void receiveTimerExpired();
91
92 /**
93 * @brief Configures the sdeventplus::source::IO object to
94 * call receive() on EPOLLIN activity on the PLDM FD
95 * which is used for command responses.
96 */
97 void registerReceiveCallback();
98
99 /**
100 * @brief Reads the MCTP endpoint ID out of a file
101 */
102 void readEID();
103
104 /**
105 * @brief Opens the PLDM file descriptor
106 */
107 void open();
108
109 /**
110 * @brief Reads the PLDM instance ID to use for the upcoming
111 * command.
112 */
113 void readInstanceID();
114
115 /**
116 * @brief Encodes and sends the PLDM 'new file available' cmd
117 *
118 * @param[in] id - The PEL ID
119 * @param[in] size - The PEL size in bytes
120 */
121 void doSend(uint32_t id, uint32_t size);
122
123 /**
124 * @brief Closes the PLDM file descriptor
125 */
126 void closeFD();
127
128 /**
129 * @brief The MCTP endpoint ID
130 */
131 mctp_eid_t _eid;
132
133 /**
134 * @brief The PLDM instance ID of the current command
135 */
136 uint8_t _instanceID;
137
138 /**
139 * @brief The PLDM command file descriptor for the current command
140 */
141 int _fd = -1;
142
143 /**
144 * @brief The event object for handling callbacks on the PLDM FD
145 */
146 std::unique_ptr<sdeventplus::source::IO> _source;
147
148 /**
149 * @brief A timer to only allow a certain amount of time for the
150 * async PLDM receive before it is considered a failure.
151 */
152 sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> _receiveTimer;
153
154 /**
155 * @brief The command timeout value
156 */
157 const std::chrono::milliseconds _receiveTimeout{10000};
158};
159
160} // namespace openpower::pels