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