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 EffecterInfo
47  *  Contains the effecter information as a whole
48  */
49 struct EffecterInfo
50 {
51     uint8_t mctpEid;         //!< Host mctp eid
52     uint16_t containerId;    //!< Container Id for host effecter
53     uint16_t entityType;     //!< Entity type for the host effecter
54     uint16_t entityInstance; //!< Entity instance for the host effecter
55     uint8_t compEffecterCnt; //!< Composite effecter count
56     std::vector<DBusEffecterMapping>
57         dbusInfo;            //!< D-Bus information for the effecter id
58 };
59 
60 /** @class HostEffecterParser
61  *
62  *  @brief This class parses the Host Effecter json file and monitors for the
63  *         D-Bus changes for the effecters. Upon change, calls the corresponding
64  *         setStateEffecterStates on the host
65  */
66 class HostEffecterParser
67 {
68   public:
69     HostEffecterParser() = delete;
70     HostEffecterParser(const HostEffecterParser&) = delete;
71     HostEffecterParser& operator=(const HostEffecterParser&) = delete;
72     HostEffecterParser(HostEffecterParser&&) = delete;
73     HostEffecterParser& operator=(HostEffecterParser&&) = delete;
74     virtual ~HostEffecterParser() = default;
75 
76     /** @brief Constructor to create a HostEffecterParser object.
77      *  @param[in] instanceIdDb - PLDM InstanceIdDb object pointer
78      *  @param[in] fd - socket fd to communicate to host
79      *  @param[in] repo -  PLDM PDR repository
80      *  @param[in] dbusHandler - D-bus Handler
81      *  @param[in] jsonPath - path for the json file
82      *  @param[in] handler - PLDM request handler
83      */
HostEffecterParser(pldm::InstanceIdDb * instanceIdDb,int fd,const pldm_pdr * repo,pldm::utils::DBusHandler * const dbusHandler,const std::string & jsonPath,pldm::requester::Handler<pldm::requester::Request> * handler)84     explicit HostEffecterParser(
85         pldm::InstanceIdDb* instanceIdDb, int fd, const pldm_pdr* repo,
86         pldm::utils::DBusHandler* const dbusHandler,
87         const std::string& jsonPath,
88         pldm::requester::Handler<pldm::requester::Request>* handler) :
89         instanceIdDb(instanceIdDb),
90         sockFd(fd), pdrRepo(repo), dbusHandler(dbusHandler), handler(handler)
91     {
92         try
93         {
94             parseEffecterJson(jsonPath);
95         }
96         catch (const std::exception& e)
97         {
98             error(
99                 "The json file '{PATH}' does not exist or malformed, error - '{ERROR}'",
100                 "PATH", jsonPath, "ERROR", e);
101         }
102     }
103 
104     /* @brief Parses the host effecter json
105      *
106      * @param[in] jsonPath - path for the json file
107      */
108     void parseEffecterJson(const std::string& jsonPath);
109 
110     /* @brief Method to take action when the subscribed D-Bus property is
111      *        changed
112      * @param[in] chProperties - list of properties which have changed
113      * @param[in] effecterInfoIndex - index of effecterInfo pointer in
114      *                                hostEffecterInfo
115      * @param[in] dbusInfoIndex - index on dbusInfo pointer in each effecterInfo
116      * @param[in] effecterId - host effecter id
117      * @return - none
118      */
119     void processHostEffecterChangeNotification(
120         const DbusChgHostEffecterProps& chProperties, size_t effecterInfoIndex,
121         size_t dbusInfoIndex, uint16_t effecterId);
122 
123     /* @brief Populate the property values in each dbusInfo from the json
124      *
125      * @param[in] dBusValues - json values
126      * @param[out] propertyValues - dbusInfo property values
127      * @param[in] propertyType - type of the D-Bus property
128      * @return - none
129      */
130     void populatePropVals(
131         const pldm::utils::Json& dBusValues,
132         std::vector<pldm::utils::PropertyValue>& propertyValues,
133         const std::string& propertyType);
134 
135     /* @brief Set a host state effecter
136      *
137      * @param[in] effecterInfoIndex - index of effecterInfo pointer in
138      *                                hostEffecterInfo
139      * @param[in] stateField - vector of state fields equal to composite
140      *                         effecter count in number
141      * @param[in] effecterId - host effecter id
142      * @return - PLDM status code
143      */
144     virtual int
145         setHostStateEffecter(size_t effecterInfoIndex,
146                              std::vector<set_effecter_state_field>& stateField,
147                              uint16_t effecterId);
148 
149     /* @brief Fetches the new state value and the index in stateField set which
150      *        needs to be set with the new value in the setStateEffecter call
151      * @param[in] effecterInfoIndex - index of effecterInfo in hostEffecterInfo
152      * @param[in] dbusInfoIndex - index of dbusInfo within effecterInfo
153      * @param[in] propertyValue - the changed D-Bus property value
154      * @return - the new state value
155      */
156     uint8_t findNewStateValue(size_t effecterInfoIndex, size_t dbusInfoIndex,
157                               const pldm::utils::PropertyValue& propertyValue);
158 
159     /* @brief Subscribes for D-Bus property change signal on the specified
160      * object
161      *
162      * @param[in] objectPath - D-Bus object path to look for
163      * @param[in] interface - D-Bus interface
164      * @param[in] effecterInfoIndex - index of effecterInfo pointer in
165      *                                hostEffecterInfo
166      * @param[in] dbusInfoIndex - index of dbusInfo within effecterInfo
167      * @param[in] effecterId - host effecter id
168      */
169     virtual void createHostEffecterMatch(const std::string& objectPath,
170                                          const std::string& interface,
171                                          size_t effecterInfoIndex,
172                                          size_t dbusInfoIndex,
173                                          uint16_t effecterId);
174 
175   protected:
176     pldm::InstanceIdDb* instanceIdDb; //!< Reference to the InstanceIdDb object
177                                       //!< to obtain instance id
178     int sockFd;                       //!< Socket fd to send message to host
179     const pldm_pdr* pdrRepo;          //!< Reference to PDR repo
180     std::vector<EffecterInfo> hostEffecterInfo; //!< Parsed effecter information
181     std::vector<std::unique_ptr<sdbusplus::bus::match_t>>
182         effecterInfoMatch; //!< vector to catch the D-Bus property change
183                            //!< signals for the effecters
184     const pldm::utils::DBusHandler* dbusHandler; //!< D-bus Handler
185     /** @brief PLDM request handler */
186     pldm::requester::Handler<pldm::requester::Request>* handler;
187 };
188 
189 } // namespace host_effecters
190 } // namespace pldm
191