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