1 #pragma once 2 3 #include "libpldm/pldm.h" 4 5 #include "common/instance_id.hpp" 6 #include "common/types.hpp" 7 #include "event_manager.hpp" 8 #include "platform_manager.hpp" 9 #include "requester/handler.hpp" 10 #include "requester/mctp_endpoint_discovery.hpp" 11 #include "sensor_manager.hpp" 12 #include "terminus_manager.hpp" 13 14 namespace pldm 15 { 16 namespace platform_mc 17 { 18 19 using PollHandler = std::function<exec::task<int>(pldm_tid_t tid)>; 20 using PollHandlers = std::vector<PollHandler>; 21 22 /** 23 * @brief Manager 24 * 25 * This class handles all the aspect of the PLDM Platform Monitoring and Control 26 * specification for the MCTP devices 27 */ 28 class Manager : public pldm::MctpDiscoveryHandlerIntf 29 { 30 public: 31 Manager() = delete; 32 Manager(const Manager&) = delete; 33 Manager(Manager&&) = delete; 34 Manager& operator=(const Manager&) = delete; 35 Manager& operator=(Manager&&) = delete; 36 ~Manager() = default; 37 Manager(sdeventplus::Event & event,RequesterHandler & handler,pldm::InstanceIdDb & instanceIdDb)38 explicit Manager(sdeventplus::Event& event, RequesterHandler& handler, 39 pldm::InstanceIdDb& instanceIdDb) : 40 terminusManager(event, handler, instanceIdDb, termini, this, 41 pldm::BmcMctpEid), 42 platformManager(terminusManager, termini), 43 sensorManager(event, terminusManager, termini, this), 44 eventManager(terminusManager, termini) 45 {} 46 47 /** @brief Helper function to do the actions before discovering terminus 48 * 49 * @return coroutine return_value - PLDM completion code 50 */ 51 exec::task<int> beforeDiscoverTerminus(); 52 53 /** @brief Helper function to do the actions after discovering terminus 54 * 55 * @return coroutine return_value - PLDM completion code 56 */ 57 exec::task<int> afterDiscoverTerminus(); 58 59 /** @brief Helper function to invoke registered handlers for 60 * the added MCTP endpoints 61 * 62 * @param[in] mctpInfos - list information of the MCTP endpoints 63 */ handleMctpEndpoints(const MctpInfos & mctpInfos)64 void handleMctpEndpoints(const MctpInfos& mctpInfos) 65 { 66 terminusManager.discoverMctpTerminus(mctpInfos); 67 } 68 69 /** @brief Helper function to invoke registered handlers for 70 * the removed MCTP endpoints 71 * 72 * @param[in] mctpInfos - list information of the MCTP endpoints 73 */ handleRemovedMctpEndpoints(const MctpInfos & mctpInfos)74 void handleRemovedMctpEndpoints(const MctpInfos& mctpInfos) 75 { 76 terminusManager.removeMctpTerminus(mctpInfos); 77 } 78 79 /** @brief Helper function to start sensor polling of the terminus TID 80 */ startSensorPolling(pldm_tid_t tid)81 void startSensorPolling(pldm_tid_t tid) 82 { 83 sensorManager.startPolling(tid); 84 } 85 86 /** @brief Helper function to set available state for pldm request (sensor 87 * polling and event polling) of the terminus TID. The `false` state 88 * will trigger stop flow in coroutine of sensor polling/event 89 * polling task to stop. 90 */ updateAvailableState(pldm_tid_t tid,Availability state)91 void updateAvailableState(pldm_tid_t tid, Availability state) 92 { 93 if (termini.contains(tid)) 94 { 95 sensorManager.updateAvailableState(tid, state); 96 eventManager.updateAvailableState(tid, state); 97 } 98 } 99 100 /** @brief Helper function to stop sensor polling of the terminus TID 101 */ stopSensorPolling(pldm_tid_t tid)102 void stopSensorPolling(pldm_tid_t tid) 103 { 104 sensorManager.stopPolling(tid); 105 } 106 107 /** @brief Sensor event handler function 108 * 109 * @param[in] request - Event message 110 * @param[in] payloadLength - Event message payload size 111 * @param[in] tid - Terminus ID 112 * @param[in] eventDataOffset - Event data offset 113 * 114 * @return PLDM error code: PLDM_SUCCESS when there is no error in handling 115 * the event 116 */ handleSensorEvent(const pldm_msg * request,size_t payloadLength,uint8_t,uint8_t tid,size_t eventDataOffset)117 int handleSensorEvent(const pldm_msg* request, size_t payloadLength, 118 uint8_t /* formatVersion */, uint8_t tid, 119 size_t eventDataOffset) 120 { 121 auto eventData = reinterpret_cast<const uint8_t*>(request->payload) + 122 eventDataOffset; 123 auto eventDataSize = payloadLength - eventDataOffset; 124 eventManager.handlePlatformEvent(tid, PLDM_PLATFORM_EVENT_ID_NULL, 125 PLDM_SENSOR_EVENT, eventData, 126 eventDataSize); 127 return PLDM_SUCCESS; 128 } 129 130 /** @brief CPER event handler function 131 * 132 * @param[in] request - Event message 133 * @param[in] payloadLength - Event message payload size 134 * @param[in] tid - Terminus ID 135 * @param[in] eventDataOffset - Event data offset 136 * 137 * @return PLDM error code: PLDM_SUCCESS when there is no error in handling 138 * the event 139 */ handleCperEvent(const pldm_msg * request,size_t payloadLength,uint8_t,uint8_t tid,size_t eventDataOffset)140 int handleCperEvent(const pldm_msg* request, size_t payloadLength, 141 uint8_t /* formatVersion */, uint8_t tid, 142 size_t eventDataOffset) 143 { 144 auto eventData = 145 const_cast<const uint8_t*>(request->payload) + eventDataOffset; 146 auto eventDataSize = payloadLength - eventDataOffset; 147 eventManager.handlePlatformEvent(tid, PLDM_PLATFORM_EVENT_ID_NULL, 148 PLDM_CPER_EVENT, eventData, 149 eventDataSize); 150 return PLDM_SUCCESS; 151 } 152 153 /** @brief PLDM POLL event handler function 154 * 155 * @param[in] request - Event message 156 * @param[in] payloadLength - Event message payload size 157 * @param[in] tid - Terminus ID 158 * @param[in] eventDataOffset - Event data offset 159 * 160 * @return PLDM error code: PLDM_SUCCESS when there is no error in handling 161 * the event 162 */ handlePldmMessagePollEvent(const pldm_msg * request,size_t payloadLength,uint8_t,uint8_t tid,size_t eventDataOffset)163 int handlePldmMessagePollEvent( 164 const pldm_msg* request, size_t payloadLength, 165 uint8_t /* formatVersion */, uint8_t tid, size_t eventDataOffset) 166 { 167 auto eventData = reinterpret_cast<const uint8_t*>(request->payload) + 168 eventDataOffset; 169 auto eventDataSize = payloadLength - eventDataOffset; 170 eventManager.handlePlatformEvent(tid, PLDM_PLATFORM_EVENT_ID_NULL, 171 PLDM_MESSAGE_POLL_EVENT, eventData, 172 eventDataSize); 173 return PLDM_SUCCESS; 174 } 175 176 /** @brief The function to trigger the event polling 177 * 178 * @param[in] tid - Terminus ID 179 * @param[in] pollEventId - The source eventID from pldmMessagePollEvent 180 * @param[in] pollDataTransferHandle - The dataTransferHandle from 181 * pldmMessagePollEvent event 182 * @return coroutine return_value - PLDM completion code 183 */ 184 exec::task<int> pollForPlatformEvent(pldm_tid_t tid, uint16_t pollEventId, 185 uint32_t pollDataTransferHandle); 186 187 /** @brief Handle Polled CPER event 188 * 189 * @param[in] tid - tid where the event is from 190 * @param[in] eventId - event Id 191 * @param[in] eventData - event data 192 * @param[in] eventDataSize - size of event data 193 * @return PLDM completion code 194 */ handlePolledCperEvent(pldm_tid_t tid,uint16_t eventId,const uint8_t * eventData,size_t eventDataSize)195 int handlePolledCperEvent(pldm_tid_t tid, uint16_t eventId, 196 const uint8_t* eventData, size_t eventDataSize) 197 { 198 return eventManager.handlePlatformEvent(tid, eventId, PLDM_CPER_EVENT, 199 eventData, eventDataSize); 200 } 201 202 /** @brief The helper function to allow register the handler function for 203 * the polled event by PollForPlatformEventMessage 204 * 205 * @param[in] eventClass - Event class 206 * @param[in] handlerFunc - Event handler 207 * 208 */ registerPolledEventHandler(uint8_t eventClass,pldm::platform_mc::HandlerFuncs handlers)209 void registerPolledEventHandler(uint8_t eventClass, 210 pldm::platform_mc::HandlerFuncs handlers) 211 { 212 eventManager.registerPolledEventHandler(eventClass, handlers); 213 } 214 215 /** @brief Register OEM flow to poll the PLDM Event use 216 * PollForPlatformEventMessage command 217 * 218 * @param[in] handler - Poll event handlerr 219 */ registerOEMPollMethod(PollHandler handler)220 void registerOEMPollMethod(PollHandler handler) 221 { 222 pollHandlers.push_back(std::move(handler)); 223 } 224 225 /** @brief OEM task to do OEM event polling 226 * 227 * @param[in] tid - Destination TID 228 * @return coroutine return_value - PLDM completion code 229 */ 230 exec::task<int> oemPollForPlatformEvent(pldm_tid_t tid); 231 232 private: 233 /** @brief List of discovered termini */ 234 TerminiMapper termini{}; 235 236 /** @brief Terminus interface for calling the hook functions */ 237 TerminusManager terminusManager; 238 239 /** @brief Platform interface for calling the hook functions */ 240 PlatformManager platformManager; 241 242 /** @brief Store platform manager handler */ 243 SensorManager sensorManager; 244 245 /** @brief Store event manager handler */ 246 EventManager eventManager; 247 248 /** @brief map of PLDM event type to EventHandlers */ 249 PollHandlers pollHandlers; 250 }; 251 } // namespace platform_mc 252 } // namespace pldm 253