1 #pragma once 2 3 #include "common/instance_id.hpp" 4 #include "common/types.hpp" 5 #include "event_manager.hpp" 6 #include "platform_manager.hpp" 7 #include "requester/handler.hpp" 8 #include "requester/mctp_endpoint_discovery.hpp" 9 #include "sensor_manager.hpp" 10 #include "terminus_manager.hpp" 11 12 #include <libpldm/pldm.h> 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, this), 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 invoke registered handlers for 80 * updating the availability status of the MCTP endpoint 81 * 82 * @param[in] mctpInfo - information of the target endpoint 83 * @param[in] availability - new availability status 84 */ updateMctpEndpointAvailability(const MctpInfo & mctpInfo,Availability availability)85 void updateMctpEndpointAvailability(const MctpInfo& mctpInfo, 86 Availability availability) 87 { 88 /* Get TID of initialized terminus */ 89 auto tid = terminusManager.toTid(mctpInfo); 90 if (tid) 91 { 92 if (availability) 93 { 94 sensorManager.startSensorPollTimer(tid.value()); 95 } 96 else 97 { 98 sensorManager.disableTerminusSensors(tid.value()); 99 } 100 updateAvailableState(tid.value(), availability); 101 } 102 terminusManager.updateMctpEndpointAvailability(mctpInfo, availability); 103 } 104 105 /** @brief Helper function to start sensor polling of the terminus TID 106 */ startSensorPolling(pldm_tid_t tid)107 void startSensorPolling(pldm_tid_t tid) 108 { 109 sensorManager.startPolling(tid); 110 } 111 112 /** @brief Helper function to set available state for pldm request (sensor 113 * polling and event polling) of the terminus TID. The `false` state 114 * will trigger stop flow in coroutine of sensor polling/event 115 * polling task to stop. 116 */ updateAvailableState(pldm_tid_t tid,Availability state)117 void updateAvailableState(pldm_tid_t tid, Availability state) 118 { 119 if (termini.contains(tid)) 120 { 121 sensorManager.updateAvailableState(tid, state); 122 eventManager.updateAvailableState(tid, state); 123 } 124 } 125 126 /** @brief Helper function to stop sensor polling of the terminus TID 127 */ stopSensorPolling(pldm_tid_t tid)128 void stopSensorPolling(pldm_tid_t tid) 129 { 130 sensorManager.stopPolling(tid); 131 } 132 133 /** @brief Sensor event handler function 134 * 135 * @param[in] request - Event message 136 * @param[in] payloadLength - Event message payload size 137 * @param[in] tid - Terminus ID 138 * @param[in] eventDataOffset - Event data offset 139 * 140 * @return PLDM error code: PLDM_SUCCESS when there is no error in handling 141 * the event 142 */ handleSensorEvent(const pldm_msg * request,size_t payloadLength,uint8_t,uint8_t tid,size_t eventDataOffset)143 int handleSensorEvent(const pldm_msg* request, size_t payloadLength, 144 uint8_t /* formatVersion */, uint8_t tid, 145 size_t eventDataOffset) 146 { 147 auto eventData = reinterpret_cast<const uint8_t*>(request->payload) + 148 eventDataOffset; 149 auto eventDataSize = payloadLength - eventDataOffset; 150 eventManager.handlePlatformEvent(tid, PLDM_PLATFORM_EVENT_ID_NULL, 151 PLDM_SENSOR_EVENT, eventData, 152 eventDataSize); 153 return PLDM_SUCCESS; 154 } 155 156 /** @brief CPER event handler function 157 * 158 * @param[in] request - Event message 159 * @param[in] payloadLength - Event message payload size 160 * @param[in] tid - Terminus ID 161 * @param[in] eventDataOffset - Event data offset 162 * 163 * @return PLDM error code: PLDM_SUCCESS when there is no error in handling 164 * the event 165 */ handleCperEvent(const pldm_msg * request,size_t payloadLength,uint8_t,uint8_t tid,size_t eventDataOffset)166 int handleCperEvent(const pldm_msg* request, size_t payloadLength, 167 uint8_t /* formatVersion */, uint8_t tid, 168 size_t eventDataOffset) 169 { 170 auto eventData = 171 const_cast<const uint8_t*>(request->payload) + eventDataOffset; 172 auto eventDataSize = payloadLength - eventDataOffset; 173 eventManager.handlePlatformEvent(tid, PLDM_PLATFORM_EVENT_ID_NULL, 174 PLDM_CPER_EVENT, eventData, 175 eventDataSize); 176 return PLDM_SUCCESS; 177 } 178 179 /** @brief PLDM POLL event handler function 180 * 181 * @param[in] request - Event message 182 * @param[in] payloadLength - Event message payload size 183 * @param[in] tid - Terminus ID 184 * @param[in] eventDataOffset - Event data offset 185 * 186 * @return PLDM error code: PLDM_SUCCESS when there is no error in handling 187 * the event 188 */ handlePldmMessagePollEvent(const pldm_msg * request,size_t payloadLength,uint8_t,uint8_t tid,size_t eventDataOffset)189 int handlePldmMessagePollEvent( 190 const pldm_msg* request, size_t payloadLength, 191 uint8_t /* formatVersion */, uint8_t tid, size_t eventDataOffset) 192 { 193 auto eventData = reinterpret_cast<const uint8_t*>(request->payload) + 194 eventDataOffset; 195 auto eventDataSize = payloadLength - eventDataOffset; 196 eventManager.handlePlatformEvent(tid, PLDM_PLATFORM_EVENT_ID_NULL, 197 PLDM_MESSAGE_POLL_EVENT, eventData, 198 eventDataSize); 199 return PLDM_SUCCESS; 200 } 201 202 /** @brief The function to trigger the event polling 203 * 204 * @param[in] tid - Terminus ID 205 * @param[in] pollEventId - The source eventID from pldmMessagePollEvent 206 * @param[in] pollDataTransferHandle - The dataTransferHandle from 207 * pldmMessagePollEvent event 208 * @return coroutine return_value - PLDM completion code 209 */ 210 exec::task<int> pollForPlatformEvent(pldm_tid_t tid, uint16_t pollEventId, 211 uint32_t pollDataTransferHandle); 212 213 /** @brief Handle Polled CPER event 214 * 215 * @param[in] tid - tid where the event is from 216 * @param[in] eventId - event Id 217 * @param[in] eventData - event data 218 * @param[in] eventDataSize - size of event data 219 * @return PLDM completion code 220 */ handlePolledCperEvent(pldm_tid_t tid,uint16_t eventId,const uint8_t * eventData,size_t eventDataSize)221 int handlePolledCperEvent(pldm_tid_t tid, uint16_t eventId, 222 const uint8_t* eventData, size_t eventDataSize) 223 { 224 return eventManager.handlePlatformEvent(tid, eventId, PLDM_CPER_EVENT, 225 eventData, eventDataSize); 226 } 227 228 /** @brief The helper function to allow register the handler function for 229 * the polled event by PollForPlatformEventMessage 230 * 231 * @param[in] eventClass - Event class 232 * @param[in] handlerFunc - Event handler 233 * 234 */ registerPolledEventHandler(uint8_t eventClass,pldm::platform_mc::HandlerFuncs handlers)235 void registerPolledEventHandler(uint8_t eventClass, 236 pldm::platform_mc::HandlerFuncs handlers) 237 { 238 eventManager.registerPolledEventHandler(eventClass, handlers); 239 } 240 241 /** @brief Register OEM flow to poll the PLDM Event use 242 * PollForPlatformEventMessage command 243 * 244 * @param[in] handler - Poll event handlerr 245 */ registerOEMPollMethod(PollHandler handler)246 void registerOEMPollMethod(PollHandler handler) 247 { 248 pollHandlers.push_back(std::move(handler)); 249 } 250 251 /** @brief OEM task to do OEM event polling 252 * 253 * @param[in] tid - Destination TID 254 * @return coroutine return_value - PLDM completion code 255 */ 256 exec::task<int> oemPollForPlatformEvent(pldm_tid_t tid); 257 258 /** @brief Get Active EIDs. 259 * 260 * @param[in] addr - MCTP address of terminus 261 * @param[in] terminiNames - MCTP terminus name 262 */ getActiveEidByName(const std::string & terminusName)263 std::optional<mctp_eid_t> getActiveEidByName( 264 const std::string& terminusName) 265 { 266 return terminusManager.getActiveEidByName(terminusName); 267 } 268 269 private: 270 /** @brief List of discovered termini */ 271 TerminiMapper termini{}; 272 273 /** @brief Terminus interface for calling the hook functions */ 274 TerminusManager terminusManager; 275 276 /** @brief Platform interface for calling the hook functions */ 277 PlatformManager platformManager; 278 279 /** @brief Store platform manager handler */ 280 SensorManager sensorManager; 281 282 /** @brief Store event manager handler */ 283 EventManager eventManager; 284 285 /** @brief map of PLDM event type to EventHandlers */ 286 PollHandlers pollHandlers; 287 }; 288 } // namespace platform_mc 289 } // namespace pldm 290