xref: /openbmc/pldm/platform-mc/event_manager.hpp (revision 6dce7d119cbfe9cacb0dd618ccfdba9f60ef05bf)
1 #pragma once
2 
3 #include "libpldm/platform.h"
4 #include "libpldm/pldm.h"
5 
6 #include "common/types.hpp"
7 #include "numeric_sensor.hpp"
8 #include "pldmd/dbus_impl_requester.hpp"
9 #include "requester/handler.hpp"
10 #include "terminus.hpp"
11 #include "terminus_manager.hpp"
12 
13 namespace pldm
14 {
15 namespace platform_mc
16 {
17 
18 using EventType = uint8_t;
19 using HandlerFunc =
20     std::function<int(pldm_tid_t tid, uint16_t eventId,
21                       const uint8_t* eventData, size_t eventDataSize)>;
22 using HandlerFuncs = std::vector<HandlerFunc>;
23 using EventMap = std::map<EventType, HandlerFuncs>;
24 
25 /**
26  * @brief EventManager
27  *
28  * This class manages PLDM events from terminus. The function includes providing
29  * the API for process event data and using phosphor-logging API to log the
30  * event.
31  *
32  */
33 class EventManager
34 {
35   public:
36     EventManager() = delete;
37     EventManager(const EventManager&) = delete;
38     EventManager(EventManager&&) = delete;
39     EventManager& operator=(const EventManager&) = delete;
40     EventManager& operator=(EventManager&&) = delete;
41     virtual ~EventManager() = default;
42 
EventManager(TerminusManager & terminusManager,TerminiMapper & termini)43     explicit EventManager(TerminusManager& terminusManager,
44                           TerminiMapper& termini) :
45         terminusManager(terminusManager), termini(termini)
46     {
47         // Default response handler for PollForPlatFormEventMessage
48         registerPolledEventHandler(
49             PLDM_MESSAGE_POLL_EVENT,
50             {[this](pldm_tid_t tid, uint16_t eventId, const uint8_t* eventData,
51                     size_t eventDataSize) {
52                 return this->handlePlatformEvent(tid, eventId,
53                                                  PLDM_MESSAGE_POLL_EVENT,
54                                                  eventData, eventDataSize);
55             }});
56         registerPolledEventHandler(
57             PLDM_CPER_EVENT,
58             {[this](pldm_tid_t tid, uint16_t eventId, const uint8_t* eventData,
59                     size_t eventDataSize) {
60                 return this->handlePlatformEvent(tid, eventId, PLDM_CPER_EVENT,
61                                                  eventData, eventDataSize);
62             }});
63     };
64 
65     /** @brief Handle platform event
66      *
67      *  @param[in] tid - tid where the event is from
68      *  @param[in] eventId - event Id
69      *  @param[in] eventClass - event class
70      *  @param[in] eventData - event data
71      *  @param[in] eventDataSize - size of event data
72      *  @return PLDM completion code
73      */
74     int handlePlatformEvent(pldm_tid_t tid, uint16_t eventId,
75                             uint8_t eventClass, const uint8_t* eventData,
76                             size_t eventDataSize);
77 
78     /** @brief Set available state of terminus for pldm request.
79      *
80      *  @param[in] tid - terminus ID
81      *  @param[in] state - Terminus available state for PLDM request messages
82      */
updateAvailableState(pldm_tid_t tid,Availability state)83     void updateAvailableState(pldm_tid_t tid, Availability state)
84     {
85         availableState[tid] = state;
86     };
87 
88     /** @brief Get available state of terminus for pldm request.
89      *
90      *  @param[in] tid - terminus ID
91      */
getAvailableState(pldm_tid_t tid)92     bool getAvailableState(pldm_tid_t tid)
93     {
94         if (!availableState.contains(tid))
95         {
96             return false;
97         }
98         return availableState[tid];
99     };
100 
101     /** @brief A Coroutine to poll all events from terminus
102      *
103      *  @param[in] tid - the destination TID
104      *  @param[in] pollDataTransferHandle - the dataTransferHandle from
105      *             pldmMessagePollEvent event
106      *  @return coroutine return_value - PLDM completion code
107      */
108     exec::task<int> pollForPlatformEventTask(pldm_tid_t tid,
109                                              uint32_t pollDataTransferHandle);
110 
111     /** @brief Register response handler for the polled events from
112      *         PollForPlatFormEventMessage
113      */
registerPolledEventHandler(uint8_t eventClass,pldm::platform_mc::HandlerFuncs handlers)114     void registerPolledEventHandler(uint8_t eventClass,
115                                     pldm::platform_mc::HandlerFuncs handlers)
116     {
117         auto [iter, inserted] = eventHandlers.try_emplace(
118             eventClass, pldm::platform_mc::HandlerFuncs{});
119 
120         for (const auto& handler : handlers)
121         {
122             iter->second.emplace_back(handler);
123         }
124     }
125 
126   protected:
127     /** @brief Helper method to process the PLDM Numeric sensor event class
128      *
129      *  @param[in] tid - tid where the event is from
130      *  @param[in] sensorId - Sensor ID which is the source of event
131      *  @param[in] sensorData - Numeric sensor event data
132      *  @param[in] sensorDataLength - event data length
133      *
134      *  @return PLDM completion code
135      */
136     int processNumericSensorEvent(pldm_tid_t tid, uint16_t sensorId,
137                                   const uint8_t* sensorData,
138                                   size_t sensorDataLength);
139 
140     /** @brief Helper method to process the PLDM CPER event class
141      *
142      *  @param[in] tid - tid where the event is from
143      *  @param[in] eventId - Event ID which is the source of event
144      *  @param[in] eventData - CPER event data
145      *  @param[in] eventDataSize - event data length
146      *
147      *  @return PLDM completion code
148      */
149     virtual int processCperEvent(pldm_tid_t tid, uint16_t eventId,
150                                  const uint8_t* eventData,
151                                  const size_t eventDataSize);
152 
153     /** @brief Helper method to create CPER dump log
154      *
155      *  @param[in] dataType - CPER event data type
156      *  @param[in] dataPath - CPER event data fault log file path
157      *  @param[in] typeName - Terminus name which creates CPER event
158      *
159      *  @return PLDM completion code
160      */
161     int createCperDumpEntry(const std::string& dataType,
162                             const std::string& dataPath,
163                             const std::string& typeName);
164 
165     /** @brief Send pollForPlatformEventMessage and return response
166      *
167      *  @param[in] tid - Destination TID
168      *  @param[in] formatVersion - format Version
169      *  @param[in] transferOpFlag - Transfer Operation Flag
170      *  @param[in] dataTransferHandle - Data transfer handle
171      *  @param[in] eventIdToAcknowledge - Event ID
172      *  @param[out] completionCode - the complete code of response message
173      *  @param[out] eventTid - Event terminus ID
174      *  @param[out] eventId - Event ID
175      *  @param[out] nextDataTransferHandle - Next handle to get next data part
176      *  @param[out] transferFlag - transfer Flag of response data
177      *  @param[out] eventClass - event class
178      *  @param[out] eventDataSize - data size of event response message
179      *  @param[out] eventData - event data of response message
180      *  @param[out] eventDataIntegrityChecksum - check sum of final event
181      *
182      *  @return coroutine return_value - PLDM completion code
183      */
184     exec::task<int> pollForPlatformEventMessage(
185         pldm_tid_t tid, uint8_t formatVersion, uint8_t transferOperationFlag,
186         uint32_t dataTransferHandle, uint16_t eventIdToAcknowledge,
187         uint8_t& completionCode, uint8_t& eventTid, uint16_t& eventId,
188         uint32_t& nextDataTransferHandle, uint8_t& transferFlag,
189         uint8_t& eventClass, uint32_t& eventDataSize, uint8_t*& eventData,
190         uint32_t& eventDataIntegrityChecksum);
191 
192     /** @brief Get the parameters for next pollForPlatformEventMessage to get
193      *         the remaining part of event if has
194      *
195      *  @param[in] eventId - Event ID
196      *  @param[in] eventMessage - event data of response message
197      *  @param[in] transferFlag - transfer Flag of response data
198      *  @param[in] eventDataIntegrityChecksum - check sum of final event
199      *  @param[in] nextDataTransferHandle - Next handle to get next data part
200      *  @param[out] transferOperationFlag - transfer Flag of next request data
201      *  @param[out] dataTransferHandle - Data transfer handle
202      *  @param[out] eventIdToAcknowledge - Event ID
203      *
204      *  @return return_value - PLDM completion code
205      */
206     int getNextPartParameters(
207         uint16_t eventId, std::vector<uint8_t> eventMessage,
208         uint8_t transferFlag, uint32_t eventDataIntegrityChecksum,
209         uint32_t nextDataTransferHandle, uint8_t* transferOperationFlag,
210         uint32_t* dataTransferHandle, uint32_t* eventIdToAcknowledge);
211 
212     /** @brief Helper function to call the event handler for polled events
213      *
214      *  @param[in] tid - terminus ID
215      *  @param[out] eventClass - Event class
216      *  @param[out] eventId - Event ID
217      *  @param[in] eventMessage - event data of response message
218      *
219      */
220     void callPolledEventHandlers(pldm_tid_t tid, uint8_t eventClass,
221                                  uint16_t eventId,
222                                  std::vector<uint8_t>& eventMessage);
223 
224     /** @brief Reference of terminusManager */
225     TerminusManager& terminusManager;
226 
227     /** @brief List of discovered termini */
228     TerminiMapper& termini;
229 
230     /** @brief Available state for pldm request of terminus */
231     std::unordered_map<pldm_tid_t, Availability> availableState;
232 
233     /** @brief map of PLDM event type of polled event to EventHandlers */
234     pldm::platform_mc::EventMap eventHandlers;
235 };
236 } // namespace platform_mc
237 } // namespace pldm
238