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