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