16c7fed4cSGilbert Chen #pragma once 26c7fed4cSGilbert Chen 36c7fed4cSGilbert Chen #include "common/instance_id.hpp" 46c7fed4cSGilbert Chen #include "common/types.hpp" 577e6fe7aSGilbert Chen #include "event_manager.hpp" 66c7fed4cSGilbert Chen #include "platform_manager.hpp" 76c7fed4cSGilbert Chen #include "requester/handler.hpp" 86c7fed4cSGilbert Chen #include "requester/mctp_endpoint_discovery.hpp" 9eac61a4bSGilbert Chen #include "sensor_manager.hpp" 106c7fed4cSGilbert Chen #include "terminus_manager.hpp" 116c7fed4cSGilbert Chen 12*fe252795SManojkiran Eda #include <libpldm/pldm.h> 13*fe252795SManojkiran Eda 146c7fed4cSGilbert Chen namespace pldm 156c7fed4cSGilbert Chen { 166c7fed4cSGilbert Chen namespace platform_mc 176c7fed4cSGilbert Chen { 186c7fed4cSGilbert Chen 195028734cSDung Cao using PollHandler = std::function<exec::task<int>(pldm_tid_t tid)>; 205028734cSDung Cao using PollHandlers = std::vector<PollHandler>; 215028734cSDung Cao 226c7fed4cSGilbert Chen /** 236c7fed4cSGilbert Chen * @brief Manager 246c7fed4cSGilbert Chen * 256c7fed4cSGilbert Chen * This class handles all the aspect of the PLDM Platform Monitoring and Control 266c7fed4cSGilbert Chen * specification for the MCTP devices 276c7fed4cSGilbert Chen */ 286c7fed4cSGilbert Chen class Manager : public pldm::MctpDiscoveryHandlerIntf 296c7fed4cSGilbert Chen { 306c7fed4cSGilbert Chen public: 316c7fed4cSGilbert Chen Manager() = delete; 326c7fed4cSGilbert Chen Manager(const Manager&) = delete; 336c7fed4cSGilbert Chen Manager(Manager&&) = delete; 346c7fed4cSGilbert Chen Manager& operator=(const Manager&) = delete; 356c7fed4cSGilbert Chen Manager& operator=(Manager&&) = delete; 366c7fed4cSGilbert Chen ~Manager() = default; 376c7fed4cSGilbert Chen Manager(sdeventplus::Event & event,RequesterHandler & handler,pldm::InstanceIdDb & instanceIdDb)386c7fed4cSGilbert Chen explicit Manager(sdeventplus::Event& event, RequesterHandler& handler, 396c7fed4cSGilbert Chen pldm::InstanceIdDb& instanceIdDb) : 4051d66b59SThu Nguyen terminusManager(event, handler, instanceIdDb, termini, this, 4151d66b59SThu Nguyen pldm::BmcMctpEid), 426baafe48SEric Yang platformManager(terminusManager, termini, this), 4377e6fe7aSGilbert Chen sensorManager(event, terminusManager, termini, this), 4477e6fe7aSGilbert Chen eventManager(terminusManager, termini) 456c7fed4cSGilbert Chen {} 466c7fed4cSGilbert Chen 476c7fed4cSGilbert Chen /** @brief Helper function to do the actions before discovering terminus 486c7fed4cSGilbert Chen * 496c7fed4cSGilbert Chen * @return coroutine return_value - PLDM completion code 506c7fed4cSGilbert Chen */ 516c7fed4cSGilbert Chen exec::task<int> beforeDiscoverTerminus(); 526c7fed4cSGilbert Chen 536c7fed4cSGilbert Chen /** @brief Helper function to do the actions after discovering terminus 546c7fed4cSGilbert Chen * 556c7fed4cSGilbert Chen * @return coroutine return_value - PLDM completion code 566c7fed4cSGilbert Chen */ 576c7fed4cSGilbert Chen exec::task<int> afterDiscoverTerminus(); 586c7fed4cSGilbert Chen 596c7fed4cSGilbert Chen /** @brief Helper function to invoke registered handlers for 606c7fed4cSGilbert Chen * the added MCTP endpoints 616c7fed4cSGilbert Chen * 626c7fed4cSGilbert Chen * @param[in] mctpInfos - list information of the MCTP endpoints 636c7fed4cSGilbert Chen */ handleMctpEndpoints(const MctpInfos & mctpInfos)646c7fed4cSGilbert Chen void handleMctpEndpoints(const MctpInfos& mctpInfos) 656c7fed4cSGilbert Chen { 666c7fed4cSGilbert Chen terminusManager.discoverMctpTerminus(mctpInfos); 676c7fed4cSGilbert Chen } 686c7fed4cSGilbert Chen 696c7fed4cSGilbert Chen /** @brief Helper function to invoke registered handlers for 706c7fed4cSGilbert Chen * the removed MCTP endpoints 716c7fed4cSGilbert Chen * 726c7fed4cSGilbert Chen * @param[in] mctpInfos - list information of the MCTP endpoints 736c7fed4cSGilbert Chen */ handleRemovedMctpEndpoints(const MctpInfos & mctpInfos)746c7fed4cSGilbert Chen void handleRemovedMctpEndpoints(const MctpInfos& mctpInfos) 756c7fed4cSGilbert Chen { 766c7fed4cSGilbert Chen terminusManager.removeMctpTerminus(mctpInfos); 776c7fed4cSGilbert Chen } 786c7fed4cSGilbert Chen 7975e00422SChau Ly /** @brief Helper function to invoke registered handlers for 8075e00422SChau Ly * updating the availability status of the MCTP endpoint 8175e00422SChau Ly * 8275e00422SChau Ly * @param[in] mctpInfo - information of the target endpoint 8375e00422SChau Ly * @param[in] availability - new availability status 8475e00422SChau Ly */ updateMctpEndpointAvailability(const MctpInfo & mctpInfo,Availability availability)8575e00422SChau Ly void updateMctpEndpointAvailability(const MctpInfo& mctpInfo, 8675e00422SChau Ly Availability availability) 8775e00422SChau Ly { 8875e00422SChau Ly /* Get TID of initialized terminus */ 8975e00422SChau Ly auto tid = terminusManager.toTid(mctpInfo); 9075e00422SChau Ly if (tid) 9175e00422SChau Ly { 9275e00422SChau Ly if (availability) 9375e00422SChau Ly { 9475e00422SChau Ly sensorManager.startSensorPollTimer(tid.value()); 9575e00422SChau Ly } 9675e00422SChau Ly else 9775e00422SChau Ly { 9875e00422SChau Ly sensorManager.disableTerminusSensors(tid.value()); 9975e00422SChau Ly } 10075e00422SChau Ly updateAvailableState(tid.value(), availability); 10175e00422SChau Ly } 10275e00422SChau Ly terminusManager.updateMctpEndpointAvailability(mctpInfo, availability); 10375e00422SChau Ly } 10475e00422SChau Ly 105eac61a4bSGilbert Chen /** @brief Helper function to start sensor polling of the terminus TID 106eac61a4bSGilbert Chen */ startSensorPolling(pldm_tid_t tid)107eac61a4bSGilbert Chen void startSensorPolling(pldm_tid_t tid) 108eac61a4bSGilbert Chen { 109eac61a4bSGilbert Chen sensorManager.startPolling(tid); 110eac61a4bSGilbert Chen } 111eac61a4bSGilbert Chen 112eac61a4bSGilbert Chen /** @brief Helper function to set available state for pldm request (sensor 113eac61a4bSGilbert Chen * polling and event polling) of the terminus TID. The `false` state 114eac61a4bSGilbert Chen * will trigger stop flow in coroutine of sensor polling/event 115eac61a4bSGilbert Chen * polling task to stop. 116eac61a4bSGilbert Chen */ updateAvailableState(pldm_tid_t tid,Availability state)117eac61a4bSGilbert Chen void updateAvailableState(pldm_tid_t tid, Availability state) 118eac61a4bSGilbert Chen { 119eac61a4bSGilbert Chen if (termini.contains(tid)) 120eac61a4bSGilbert Chen { 121eac61a4bSGilbert Chen sensorManager.updateAvailableState(tid, state); 12277e6fe7aSGilbert Chen eventManager.updateAvailableState(tid, state); 123eac61a4bSGilbert Chen } 124eac61a4bSGilbert Chen } 125eac61a4bSGilbert Chen 126eac61a4bSGilbert Chen /** @brief Helper function to stop sensor polling of the terminus TID 127eac61a4bSGilbert Chen */ stopSensorPolling(pldm_tid_t tid)128eac61a4bSGilbert Chen void stopSensorPolling(pldm_tid_t tid) 129eac61a4bSGilbert Chen { 130eac61a4bSGilbert Chen sensorManager.stopPolling(tid); 131eac61a4bSGilbert Chen } 132eac61a4bSGilbert Chen 1339fc79128SThu Nguyen /** @brief Sensor event handler function 13477e6fe7aSGilbert Chen * 13577e6fe7aSGilbert Chen * @param[in] request - Event message 13677e6fe7aSGilbert Chen * @param[in] payloadLength - Event message payload size 13777e6fe7aSGilbert Chen * @param[in] tid - Terminus ID 13877e6fe7aSGilbert Chen * @param[in] eventDataOffset - Event data offset 13977e6fe7aSGilbert Chen * 14077e6fe7aSGilbert Chen * @return PLDM error code: PLDM_SUCCESS when there is no error in handling 14177e6fe7aSGilbert Chen * the event 14277e6fe7aSGilbert Chen */ handleSensorEvent(const pldm_msg * request,size_t payloadLength,uint8_t,uint8_t tid,size_t eventDataOffset)14377e6fe7aSGilbert Chen int handleSensorEvent(const pldm_msg* request, size_t payloadLength, 14477e6fe7aSGilbert Chen uint8_t /* formatVersion */, uint8_t tid, 14577e6fe7aSGilbert Chen size_t eventDataOffset) 14677e6fe7aSGilbert Chen { 14777e6fe7aSGilbert Chen auto eventData = reinterpret_cast<const uint8_t*>(request->payload) + 14877e6fe7aSGilbert Chen eventDataOffset; 14977e6fe7aSGilbert Chen auto eventDataSize = payloadLength - eventDataOffset; 1509fc79128SThu Nguyen eventManager.handlePlatformEvent(tid, PLDM_PLATFORM_EVENT_ID_NULL, 1519fc79128SThu Nguyen PLDM_SENSOR_EVENT, eventData, 1529fc79128SThu Nguyen eventDataSize); 1539fc79128SThu Nguyen return PLDM_SUCCESS; 1549fc79128SThu Nguyen } 1559fc79128SThu Nguyen 1569fc79128SThu Nguyen /** @brief CPER event handler function 1579fc79128SThu Nguyen * 1589fc79128SThu Nguyen * @param[in] request - Event message 1599fc79128SThu Nguyen * @param[in] payloadLength - Event message payload size 1609fc79128SThu Nguyen * @param[in] tid - Terminus ID 1619fc79128SThu Nguyen * @param[in] eventDataOffset - Event data offset 1629fc79128SThu Nguyen * 1639fc79128SThu Nguyen * @return PLDM error code: PLDM_SUCCESS when there is no error in handling 1649fc79128SThu Nguyen * the event 1659fc79128SThu Nguyen */ handleCperEvent(const pldm_msg * request,size_t payloadLength,uint8_t,uint8_t tid,size_t eventDataOffset)1669fc79128SThu Nguyen int handleCperEvent(const pldm_msg* request, size_t payloadLength, 1679fc79128SThu Nguyen uint8_t /* formatVersion */, uint8_t tid, 1689fc79128SThu Nguyen size_t eventDataOffset) 1699fc79128SThu Nguyen { 1709fc79128SThu Nguyen auto eventData = 1719fc79128SThu Nguyen const_cast<const uint8_t*>(request->payload) + eventDataOffset; 1729fc79128SThu Nguyen auto eventDataSize = payloadLength - eventDataOffset; 1739fc79128SThu Nguyen eventManager.handlePlatformEvent(tid, PLDM_PLATFORM_EVENT_ID_NULL, 1749fc79128SThu Nguyen PLDM_CPER_EVENT, eventData, 1759fc79128SThu Nguyen eventDataSize); 17677e6fe7aSGilbert Chen return PLDM_SUCCESS; 17777e6fe7aSGilbert Chen } 17877e6fe7aSGilbert Chen 179f48015b3SDung Cao /** @brief PLDM POLL event handler function 180f48015b3SDung Cao * 181f48015b3SDung Cao * @param[in] request - Event message 182f48015b3SDung Cao * @param[in] payloadLength - Event message payload size 183f48015b3SDung Cao * @param[in] tid - Terminus ID 184f48015b3SDung Cao * @param[in] eventDataOffset - Event data offset 185f48015b3SDung Cao * 186f48015b3SDung Cao * @return PLDM error code: PLDM_SUCCESS when there is no error in handling 187f48015b3SDung Cao * the event 188f48015b3SDung Cao */ handlePldmMessagePollEvent(const pldm_msg * request,size_t payloadLength,uint8_t,uint8_t tid,size_t eventDataOffset)189f48015b3SDung Cao int handlePldmMessagePollEvent( 190f48015b3SDung Cao const pldm_msg* request, size_t payloadLength, 191f48015b3SDung Cao uint8_t /* formatVersion */, uint8_t tid, size_t eventDataOffset) 192f48015b3SDung Cao { 193f48015b3SDung Cao auto eventData = reinterpret_cast<const uint8_t*>(request->payload) + 194f48015b3SDung Cao eventDataOffset; 195f48015b3SDung Cao auto eventDataSize = payloadLength - eventDataOffset; 196f48015b3SDung Cao eventManager.handlePlatformEvent(tid, PLDM_PLATFORM_EVENT_ID_NULL, 197f48015b3SDung Cao PLDM_MESSAGE_POLL_EVENT, eventData, 198f48015b3SDung Cao eventDataSize); 199f48015b3SDung Cao return PLDM_SUCCESS; 200f48015b3SDung Cao } 201f48015b3SDung Cao 202f48015b3SDung Cao /** @brief The function to trigger the event polling 203f48015b3SDung Cao * 204f48015b3SDung Cao * @param[in] tid - Terminus ID 205f48015b3SDung Cao * @param[in] pollEventId - The source eventID from pldmMessagePollEvent 206f48015b3SDung Cao * @param[in] pollDataTransferHandle - The dataTransferHandle from 207f48015b3SDung Cao * pldmMessagePollEvent event 208f48015b3SDung Cao * @return coroutine return_value - PLDM completion code 209f48015b3SDung Cao */ 210f48015b3SDung Cao exec::task<int> pollForPlatformEvent(pldm_tid_t tid, uint16_t pollEventId, 211f48015b3SDung Cao uint32_t pollDataTransferHandle); 212f48015b3SDung Cao 2136894e90fSThu Nguyen /** @brief Handle Polled CPER event 2146894e90fSThu Nguyen * 2156894e90fSThu Nguyen * @param[in] tid - tid where the event is from 2166894e90fSThu Nguyen * @param[in] eventId - event Id 2176894e90fSThu Nguyen * @param[in] eventData - event data 2186894e90fSThu Nguyen * @param[in] eventDataSize - size of event data 2196894e90fSThu Nguyen * @return PLDM completion code 2206894e90fSThu Nguyen */ handlePolledCperEvent(pldm_tid_t tid,uint16_t eventId,const uint8_t * eventData,size_t eventDataSize)2216894e90fSThu Nguyen int handlePolledCperEvent(pldm_tid_t tid, uint16_t eventId, 2226894e90fSThu Nguyen const uint8_t* eventData, size_t eventDataSize) 2236894e90fSThu Nguyen { 2246894e90fSThu Nguyen return eventManager.handlePlatformEvent(tid, eventId, PLDM_CPER_EVENT, 2256894e90fSThu Nguyen eventData, eventDataSize); 2266894e90fSThu Nguyen } 2276894e90fSThu Nguyen 2286894e90fSThu Nguyen /** @brief The helper function to allow register the handler function for 2296894e90fSThu Nguyen * the polled event by PollForPlatformEventMessage 2306894e90fSThu Nguyen * 2316894e90fSThu Nguyen * @param[in] eventClass - Event class 2326894e90fSThu Nguyen * @param[in] handlerFunc - Event handler 2336894e90fSThu Nguyen * 2346894e90fSThu Nguyen */ registerPolledEventHandler(uint8_t eventClass,pldm::platform_mc::HandlerFuncs handlers)2356894e90fSThu Nguyen void registerPolledEventHandler(uint8_t eventClass, 2366dce7d11SThu Nguyen pldm::platform_mc::HandlerFuncs handlers) 2376894e90fSThu Nguyen { 2386dce7d11SThu Nguyen eventManager.registerPolledEventHandler(eventClass, handlers); 2396894e90fSThu Nguyen } 2406894e90fSThu Nguyen 2415028734cSDung Cao /** @brief Register OEM flow to poll the PLDM Event use 2425028734cSDung Cao * PollForPlatformEventMessage command 2435028734cSDung Cao * 2445028734cSDung Cao * @param[in] handler - Poll event handlerr 2455028734cSDung Cao */ registerOEMPollMethod(PollHandler handler)2465028734cSDung Cao void registerOEMPollMethod(PollHandler handler) 2475028734cSDung Cao { 2485028734cSDung Cao pollHandlers.push_back(std::move(handler)); 2495028734cSDung Cao } 2505028734cSDung Cao 2515028734cSDung Cao /** @brief OEM task to do OEM event polling 2525028734cSDung Cao * 2535028734cSDung Cao * @param[in] tid - Destination TID 2545028734cSDung Cao * @return coroutine return_value - PLDM completion code 2555028734cSDung Cao */ 2565028734cSDung Cao exec::task<int> oemPollForPlatformEvent(pldm_tid_t tid); 2575028734cSDung Cao 25838e12aa2SThu Nguyen /** @brief Get Active EIDs. 25938e12aa2SThu Nguyen * 26038e12aa2SThu Nguyen * @param[in] addr - MCTP address of terminus 26138e12aa2SThu Nguyen * @param[in] terminiNames - MCTP terminus name 26238e12aa2SThu Nguyen */ getActiveEidByName(const std::string & terminusName)26338e12aa2SThu Nguyen std::optional<mctp_eid_t> getActiveEidByName( 26438e12aa2SThu Nguyen const std::string& terminusName) 26538e12aa2SThu Nguyen { 26638e12aa2SThu Nguyen return terminusManager.getActiveEidByName(terminusName); 26738e12aa2SThu Nguyen } 26838e12aa2SThu Nguyen 2696c7fed4cSGilbert Chen private: 2706c7fed4cSGilbert Chen /** @brief List of discovered termini */ 2716c7fed4cSGilbert Chen TerminiMapper termini{}; 2726c7fed4cSGilbert Chen 2736c7fed4cSGilbert Chen /** @brief Terminus interface for calling the hook functions */ 2746c7fed4cSGilbert Chen TerminusManager terminusManager; 2756c7fed4cSGilbert Chen 2766c7fed4cSGilbert Chen /** @brief Platform interface for calling the hook functions */ 2776c7fed4cSGilbert Chen PlatformManager platformManager; 278eac61a4bSGilbert Chen 279eac61a4bSGilbert Chen /** @brief Store platform manager handler */ 280eac61a4bSGilbert Chen SensorManager sensorManager; 28177e6fe7aSGilbert Chen 28277e6fe7aSGilbert Chen /** @brief Store event manager handler */ 28377e6fe7aSGilbert Chen EventManager eventManager; 2845028734cSDung Cao 2855028734cSDung Cao /** @brief map of PLDM event type to EventHandlers */ 2865028734cSDung Cao PollHandlers pollHandlers; 2876c7fed4cSGilbert Chen }; 2886c7fed4cSGilbert Chen } // namespace platform_mc 2896c7fed4cSGilbert Chen } // namespace pldm 290