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