1 #pragma once
2 
3 #include "libpldmresponder/platform.hpp"
4 
5 #include <libpldm/pdr.h>
6 #include <libpldm/platform.h>
7 
8 #include <sdbusplus/bus/match.hpp>
9 #include <sdeventplus/event.hpp>
10 #include <sdeventplus/utility/timer.hpp>
11 
12 #include <memory>
13 
14 namespace pldm
15 {
16 
17 using namespace sdbusplus::bus::match::rules;
18 
19 namespace responder
20 {
21 
22 using ObjectPath = std::string;
23 using AssociatedEntityMap = std::map<ObjectPath, pldm_entity>;
24 
25 /** @class SlotHandler
26  *
27  *  @brief This class performs the necessary operation in pldm for
28  *         Slot Enable operation. That includes taking actions on the
29  *         setStateEffecterStates calls from Host and also sending
30  *         notification to inventory manager application
31  */
32 class SlotHandler
33 {
34   public:
35     SlotHandler() = delete;
36     ~SlotHandler() = default;
37     SlotHandler(const SlotHandler&) = delete;
38     SlotHandler& operator=(const SlotHandler&) = delete;
39     SlotHandler(SlotHandler&&) = delete;
40     SlotHandler& operator=(SlotHandler&&) = delete;
41 
42     /** @brief SlotHandler Constructor
43      *
44      * @param[in] event - reference for the main event loop
45      * @param[in] repo - pointer to the BMC's Primary PDR repo
46      *
47      */
SlotHandler(const sdeventplus::Event & event,pldm_pdr * repo)48     SlotHandler(const sdeventplus::Event& event, pldm_pdr* repo) :
49         timer(event,
50               std::bind(std::mem_fn(&SlotHandler::timeOutHandler), this)),
51         pdrRepo(repo)
52     {
53         fruPresenceMatch = nullptr;
54         currentOnGoingSlotEntity.entity_type = 0;
55         currentOnGoingSlotEntity.entity_instance_num = 0;
56         currentOnGoingSlotEntity.entity_container_id = 0;
57     }
58 
59     /** @brief Method to be called when enabling a Slot for ADD/REMOVE/REPLACE
60      *  @param[in] effecterID - The effecter ID of the effecter that is set from
61      *                          host
62      *  @param[in] fruAssociationMap - the dbus path to pldm entity stored while
63      *                                 creating the pldm fru records
64      *  @param[in] stateFieldValue - the current Effecter stateFieldValue
65      */
66     void enableSlot(uint16_t effecterId,
67                     const AssociatedEntityMap& fruAssociationMap,
68                     uint8_t stateFieldValue);
69 
70     /** @brief Method to be used for fetching the slot sensor value
71      *  @param[in] slotObjectPath - the dbus object path for slot object
72      *  @return - returns the sensor state for the respective slot sensor
73      */
74     uint8_t fetchSlotSensorState(const std::string& slotObjectPath);
75 
76     /** @brief Method to set the oem platform handler in SlotHandler class
77      *  @param[in] handler - pointer to the oem platform handler
78      */
79     void setOemPlatformHandler(pldm::responder::oem_platform::Handler* handler);
80 
81   private:
82     /** @brief call back method called when the timer is expired. This handler
83      *  is called when the change of state cannot be made for a slot.
84      */
85     void timeOutHandler();
86 
87     /** @brief Abstracted method for obtaining the entityID from effecterID
88      *  @param[in]  effecterID - The effecterID of the BMC effecter
89      *  @return - pldm entity ID for the given effecter ID
90      */
91     pldm_entity getEntityIDfromEffecterID(uint16_t effecterID);
92 
93     /** @brief Abstracted method for processing the Slot Operations
94      *  @param[in] slotObjPath - The slot dbus object path
95      *  @param[in] entity - the current slot pldm entity under operation
96      *  @param[in] stateFieldValue - the current Effecter stateFieldValue
97      */
98     void processSlotOperations(const std::string& slotObjectPath,
99                                const pldm_entity& entity,
100                                uint8_t stateFieldValue);
101 
102     /** @brief Method to obtain the Adapter dbus Object Path from Slot Adapter
103      * path
104      *  @param[in] slotObjPath - The slot dbus object path
105      *  @return - if Successfull, returns the adapter dbus object path
106      */
107     std::optional<std::string>
108         getAdapterObjPath(const std::string& slotObjPath);
109 
110     /** @brief Method to call VPD collection & VPD removal API's
111      *  @param[in] adapterObjectPath - The adapter D-Bus object path
112      *  @param[in] stateFieldvalue - The current stateField value from set
113      *                               effecter call
114      */
115     void callVPDManager(const std::string& adapterObjPath,
116                         uint8_t stateFieldValue);
117 
118     /** @brief Method to create a matcher to catch the property change signal
119      *  @param[in] adapterObjectPath - The adapter D-Bus object path
120      *  @param[in] stateFieldvalue - The current stateField value from set
121      *                               effecter call
122      *  @param[in] entity - the current slot pldm entity under operation
123      */
124     void createPresenceMatch(const std::string& adapterObjectPath,
125                              const pldm_entity& entity,
126                              uint8_t stateFieldValue);
127 
128     /** @brief Method to process the Property change signal from Preset Property
129      *  @param[in] presentValue - The current value of present Value
130      *  @param[in] stateFieldvalue - The current stateField value from set
131      *                               effecter call
132      *  @param[in] entity - the current slot pldm entity under operation
133      */
134     void processPresentPropertyChange(
135         bool presentValue, uint8_t stateFieldvalue, const pldm_entity& entity);
136 
137     /** @brief Get the sensor state from D-Bus
138      *  @param[in] adapterObjectPath - reference of the Adapter dbus object path
139      *  @return - Boolean value of sensor state
140      */
141 
142     bool fetchSensorStateFromDbus(const std::string& adapterObjectPath);
143 
144     /* @brief Method to send a state sensor event to Host from SlotHandler class
145      * @param[in] sensorId - sensor id for the event
146      * @param[in] sensorEventClass - sensor event class wrt DSP0248
147      * @param[in] sensorOffset - sensor offset
148      * @param[in] eventState - new event state
149      * @param[in] prevEventState - previous state
150      */
151     void sendStateSensorEvent(uint16_t sensorId,
152                               enum sensor_event_class_states sensorEventClass,
153                               uint8_t sensorOffset, uint8_t eventState,
154                               uint8_t prevEventState);
155 
156     pldm::responder::oem_platform::Handler* oemPlatformHandler =
157         nullptr; //!< oem platform handler
158 
159     /** @brief pointer to tha matcher for Present State for adapter object*/
160     std::unique_ptr<sdbusplus::bus::match_t> fruPresenceMatch;
161 
162     /** @brief Timer used for Slot VPD Collection operation */
163     sdeventplus::utility::Timer<sdeventplus::ClockId::Monotonic> timer;
164 
165     /** @brief pointer to BMC's primary PDR repo */
166     const pldm_pdr* pdrRepo;
167 
168     /** @brief variable to store the current slot entity under operation */
169     pldm_entity currentOnGoingSlotEntity;
170 };
171 
172 } // namespace responder
173 } // namespace pldm
174