1 #pragma once
2 
3 #include "common/instance_id.hpp"
4 #include "common/types.hpp"
5 #include "common/utils.hpp"
6 #include "requester/handler.hpp"
7 
8 #include <phosphor-logging/lg2.hpp>
9 
10 #include <string>
11 #include <utility>
12 #include <vector>
13 
14 PHOSPHOR_LOG2_USING;
15 
16 namespace pldm
17 {
18 
19 namespace host_effecters
20 {
21 
22 using DbusChgHostEffecterProps =
23     std::map<dbus::Property, pldm::utils::PropertyValue>;
24 
25 /** @struct State
26  *  Contains the state set id and the possible states for
27  *  an effecter
28  */
29 struct PossibleState
30 {
31     uint16_t stateSetId;         //!< State set id
32     std::vector<uint8_t> states; //!< Possible states
33 };
34 
35 /** @struct DBusEffecterMapping
36  *  Contains the D-Bus information for an effecter
37  */
38 struct DBusEffecterMapping
39 {
40     pldm::utils::DBusMapping dbusMap;
41     std::vector<pldm::utils::PropertyValue>
42         propertyValues;  //!< D-Bus property values
43     PossibleState state; //!< Corresponding effecter states
44 };
45 
46 /** @struct DBusEffecterMapping
47  *  Contains the D-Bus information for an effecter
48  */
49 struct DBusNumericEffecterMapping
50 {
51     pldm::utils::DBusMapping dbusMap;
52     uint8_t dataSize;     //!< Numeric effecter PDR data size
53     double resolution;    //!< Numeric effecter PDR resolution
54     double offset;        //!< Numeric effecter PDR offset
55     int8_t unitModifier;  //!< Numeric effecter PDR unitModifier
56     double propertyValue; //!< D-Bus property values
57 };
58 
59 /** @struct EffecterInfo
60  *  Contains the effecter information as a whole
61  */
62 struct EffecterInfo
63 {
64     uint8_t mctpEid;             //!< Host mctp eid
65     uint8_t effecterPdrType;     //!< Effecter PDR type state/numeric
66     uint16_t containerId;        //!< Container Id for host effecter
67     uint16_t entityType;         //!< Entity type for the host effecter
68     uint16_t entityInstance;     //!< Entity instance for the host effecter
69     uint8_t compEffecterCnt;     //!< Composite effecter count
70     bool checkHostState;         //!< Check host state before setting effecter
71     std::vector<DBusEffecterMapping>
72         dbusInfo;                //!< D-Bus information for the effecter id
73     std::vector<DBusNumericEffecterMapping>
74         dbusNumericEffecterInfo; //!< D-Bus information for the effecter id
75 };
76 
77 /** @class HostEffecterParser
78  *
79  *  @brief This class parses the Host Effecter json file and monitors for the
80  *         D-Bus changes for the effecters. Upon change, calls the corresponding
81  *         setStateEffecterStates on the host
82  */
83 class HostEffecterParser
84 {
85   public:
86     HostEffecterParser() = delete;
87     HostEffecterParser(const HostEffecterParser&) = delete;
88     HostEffecterParser& operator=(const HostEffecterParser&) = delete;
89     HostEffecterParser(HostEffecterParser&&) = delete;
90     HostEffecterParser& operator=(HostEffecterParser&&) = delete;
91     virtual ~HostEffecterParser() = default;
92 
93     /** @brief Constructor to create a HostEffecterParser object.
94      *  @param[in] instanceIdDb - PLDM InstanceIdDb object pointer
95      *  @param[in] fd - socket fd to communicate to host
96      *  @param[in] repo -  PLDM PDR repository
97      *  @param[in] dbusHandler - D-bus Handler
98      *  @param[in] jsonPath - path for the json file
99      *  @param[in] handler - PLDM request handler
100      */
101     explicit HostEffecterParser(
102         pldm::InstanceIdDb* instanceIdDb, int fd, const pldm_pdr* repo,
103         pldm::utils::DBusHandler* const dbusHandler,
104         const std::string& jsonPath,
105         pldm::requester::Handler<pldm::requester::Request>* handler) :
106         instanceIdDb(instanceIdDb), sockFd(fd), pdrRepo(repo),
107         dbusHandler(dbusHandler), handler(handler)
108     {
109         try
110         {
111             parseEffecterJson(jsonPath);
112         }
113         catch (const std::exception& e)
114         {
115             error(
116                 "The json file '{PATH}' does not exist or malformed, error - '{ERROR}'",
117                 "PATH", jsonPath, "ERROR", e);
118         }
119     }
120 
121     /* @brief Parses the host effecter json
122      *
123      * @param[in] jsonPath - path for the json file
124      */
125     void parseEffecterJson(const std::string& jsonPath);
126 
127     /* @brief Method to take action when the subscribed D-Bus property is
128      *        changed
129      * @param[in] chProperties - list of properties which have changed
130      * @param[in] effecterInfoIndex - index of effecterInfo pointer in
131      *                                hostEffecterInfo
132      * @param[in] dbusInfoIndex - index on dbusInfo pointer in each effecterInfo
133      * @param[in] effecterId - host effecter id
134      * @return - none
135      */
136     void processHostEffecterChangeNotification(
137         const DbusChgHostEffecterProps& chProperties, size_t effecterInfoIndex,
138         size_t dbusInfoIndex, uint16_t effecterId);
139 
140     /* @brief Method to take action when the subscribed D-Bus property is
141      *        changed
142      * @param[in] chProperties - list of properties which have changed
143      * @param[in] effecterInfoIndex - index of effecterInfo pointer in
144      *                                hostEffecterInfo
145      * @param[in] dbusInfoIndex - index on dbusInfo pointer in each effecterInfo
146 
147      * @param[in] effecterId - terminus numeric effecter id
148      * @return - none
149      */
150     void processTerminusNumericEffecterChangeNotification(
151         const DbusChgHostEffecterProps& chProperties, size_t effecterInfoIndex,
152         size_t dbusInfoIndex, uint16_t effecterId);
153 
154     /* @brief Populate the property values in each dbusInfo from the json
155      *
156      * @param[in] dBusValues - json values
157      * @param[out] propertyValues - dbusInfo property values
158      * @param[in] propertyType - type of the D-Bus property
159      * @return - none
160      */
161     void populatePropVals(
162         const pldm::utils::Json& dBusValues,
163         std::vector<pldm::utils::PropertyValue>& propertyValues,
164         const std::string& propertyType);
165 
166     /* @brief Set a host state effecter
167      *
168      * @param[in] effecterInfoIndex - index of effecterInfo pointer in
169      *                                hostEffecterInfo
170      * @param[in] stateField - vector of state fields equal to composite
171      *                         effecter count in number
172      * @param[in] effecterId - host effecter id
173      * @return - PLDM status code
174      */
175     virtual int setHostStateEffecter(
176         size_t effecterInfoIndex,
177         std::vector<set_effecter_state_field>& stateField, uint16_t effecterId);
178 
179     /* @brief Set a terminus numeric effecter
180      *
181      * @param[in] effecterInfoIndex - index of effecterInfo pointer in
182      *                                hostEffecterInfo
183      * @param[in] effecterId - host effecter id
184      * @param[in] dataSize - data size
185      * @param[in] rawValue - raw value
186      * @return - PLDM status code
187      */
188     virtual int setTerminusNumericEffecter(size_t effecterInfoIndex,
189                                            uint16_t effecterId,
190                                            uint8_t dataSize, double rawValue);
191 
192     /* @brief Fetches the new state value and the index in stateField set which
193      *        needs to be set with the new value in the setStateEffecter call
194      * @param[in] effecterInfoIndex - index of effecterInfo in hostEffecterInfo
195      * @param[in] dbusInfoIndex - index of dbusInfo within effecterInfo
196      * @param[in] propertyValue - the changed D-Bus property value
197      * @return - the new state value
198      */
199     uint8_t findNewStateValue(size_t effecterInfoIndex, size_t dbusInfoIndex,
200                               const pldm::utils::PropertyValue& propertyValue);
201 
202     /* @brief Subscribes for D-Bus property change signal on the specified
203      *        object
204      *
205      * @param[in] objectPath - D-Bus object path to look for
206      * @param[in] interface - D-Bus interface
207      * @param[in] effecterInfoIndex - index of effecterInfo pointer in
208      *                                hostEffecterInfo
209      * @param[in] dbusInfoIndex - index of dbusInfo within effecterInfo
210      * @param[in] effecterId - host effecter id
211      */
212     virtual void createHostEffecterMatch(
213         const std::string& objectPath, const std::string& interface,
214         size_t effecterInfoIndex, size_t dbusInfoIndex, uint16_t effecterId);
215 
216     /* @brief Adjust the numeric effecter value base on the effecter
217      *        configurations
218      *
219      * @param[in] value - Raw value
220      * @param[in] offset - offset config
221      * @param[in] resolution - resolution config
222      * @param[in] modify - modify config
223      *
224      * @return - Value of effecter
225      */
226     double adjustValue(double value, double offset, double resolution,
227                        int8_t modify);
228 
229   private:
230     /* @brief Verify host On state before configure the host effecters
231      *
232      * @return - true if host is on and false for others cases
233      */
234     bool isHostOn(void);
235 
236   protected:
237     pldm::InstanceIdDb* instanceIdDb; //!< Reference to the InstanceIdDb object
238                                       //!< to obtain instance id
239     int sockFd;                       //!< Socket fd to send message to host
240     const pldm_pdr* pdrRepo;          //!< Reference to PDR repo
241     std::vector<EffecterInfo> hostEffecterInfo; //!< Parsed effecter information
242     std::vector<std::unique_ptr<sdbusplus::bus::match_t>>
243         effecterInfoMatch; //!< vector to catch the D-Bus property change
244                            //!< signals for the effecters
245     const pldm::utils::DBusHandler* dbusHandler; //!< D-bus Handler
246     /** @brief PLDM request handler */
247     pldm::requester::Handler<pldm::requester::Request>* handler;
248 };
249 
250 } // namespace host_effecters
251 } // namespace pldm
252