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 EventMap = std::map<EventType, HandlerFunc>;
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 
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      */
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      */
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      */
113     void registerPolledEventHandler(uint8_t eventClass, HandlerFunc function)
114     {
115         eventHandlers.insert_or_assign(eventClass, std::move(function));
116     }
117 
118   protected:
119     /** @brief Helper method to process the PLDM Numeric sensor event class
120      *
121      *  @param[in] tid - tid where the event is from
122      *  @param[in] sensorId - Sensor ID which is the source of event
123      *  @param[in] sensorData - Numeric sensor event data
124      *  @param[in] sensorDataLength - event data length
125      *
126      *  @return PLDM completion code
127      */
128     int processNumericSensorEvent(pldm_tid_t tid, uint16_t sensorId,
129                                   const uint8_t* sensorData,
130                                   size_t sensorDataLength);
131 
132     /** @brief Helper method to process the PLDM CPER event class
133      *
134      *  @param[in] tid - tid where the event is from
135      *  @param[in] eventId - Event ID which is the source of event
136      *  @param[in] eventData - CPER event data
137      *  @param[in] eventDataSize - event data length
138      *
139      *  @return PLDM completion code
140      */
141     virtual int processCperEvent(pldm_tid_t tid, uint16_t eventId,
142                                  const uint8_t* eventData,
143                                  const size_t eventDataSize);
144 
145     /** @brief Helper method to create CPER dump log
146      *
147      *  @param[in] dataType - CPER event data type
148      *  @param[in] dataPath - CPER event data fault log file path
149      *  @param[in] typeName - Terminus name which creates CPER event
150      *
151      *  @return PLDM completion code
152      */
153     int createCperDumpEntry(const std::string& dataType,
154                             const std::string& dataPath,
155                             const std::string& typeName);
156 
157     /** @brief Send pollForPlatformEventMessage and return response
158      *
159      *  @param[in] tid - Destination TID
160      *  @param[in] formatVersion - format Version
161      *  @param[in] transferOpFlag - Transfer Operation Flag
162      *  @param[in] dataTransferHandle - Data transfer handle
163      *  @param[in] eventIdToAcknowledge - Event ID
164      *  @param[out] completionCode - the complete code of response message
165      *  @param[out] eventTid - Event terminus ID
166      *  @param[out] eventId - Event ID
167      *  @param[out] nextDataTransferHandle - Next handle to get next data part
168      *  @param[out] transferFlag - transfer Flag of response data
169      *  @param[out] eventClass - event class
170      *  @param[out] eventDataSize - data size of event response message
171      *  @param[out] eventData - event data of response message
172      *  @param[out] eventDataIntegrityChecksum - check sum of final event
173      *
174      *  @return coroutine return_value - PLDM completion code
175      */
176     exec::task<int> pollForPlatformEventMessage(
177         pldm_tid_t tid, uint8_t formatVersion, uint8_t transferOperationFlag,
178         uint32_t dataTransferHandle, uint16_t eventIdToAcknowledge,
179         uint8_t& completionCode, uint8_t& eventTid, uint16_t& eventId,
180         uint32_t& nextDataTransferHandle, uint8_t& transferFlag,
181         uint8_t& eventClass, uint32_t& eventDataSize, uint8_t*& eventData,
182         uint32_t& eventDataIntegrityChecksum);
183 
184     /** @brief Get the parameters for next pollForPlatformEventMessage to get
185      *         the remaining part of event if has
186      *
187      *  @param[in] eventId - Event ID
188      *  @param[in] eventMessage - event data of response message
189      *  @param[in] transferFlag - transfer Flag of response data
190      *  @param[in] eventDataIntegrityChecksum - check sum of final event
191      *  @param[in] nextDataTransferHandle - Next handle to get next data part
192      *  @param[out] transferOperationFlag - transfer Flag of next request data
193      *  @param[out] dataTransferHandle - Data transfer handle
194      *  @param[out] eventIdToAcknowledge - Event ID
195      *
196      *  @return return_value - PLDM completion code
197      */
198     int getNextPartParameters(
199         uint16_t eventId, std::vector<uint8_t> eventMessage,
200         uint8_t transferFlag, uint32_t eventDataIntegrityChecksum,
201         uint32_t nextDataTransferHandle, uint8_t* transferOperationFlag,
202         uint32_t* dataTransferHandle, uint32_t* eventIdToAcknowledge);
203 
204     /** @brief Reference of terminusManager */
205     TerminusManager& terminusManager;
206 
207     /** @brief List of discovered termini */
208     TerminiMapper& termini;
209 
210     /** @brief Available state for pldm request of terminus */
211     std::unordered_map<pldm_tid_t, Availability> availableState;
212 
213     /** @brief map of PLDM event type of polled event to EventHandlers */
214     pldm::platform_mc::EventMap eventHandlers;
215 };
216 } // namespace platform_mc
217 } // namespace pldm
218