xref: /openbmc/pldm/platform-mc/manager.hpp (revision fe2527954be36a3013dc6b8c8ff13ae649bb58a6)
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