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