1 #pragma once
2 
3 #include "common/types.hpp"
4 #include "common/utils.hpp"
5 #include "pldmd/dbus_impl_requester.hpp"
6 #include "requester/handler.hpp"
7 
8 #include <string>
9 #include <utility>
10 #include <vector>
11 
12 namespace pldm
13 {
14 
15 namespace host_effecters
16 {
17 
18 using DbusChgHostEffecterProps =
19     std::map<dbus::Property, pldm::utils::PropertyValue>;
20 
21 /** @struct State
22  *  Contains the state set id and the possible states for
23  *  an effecter
24  */
25 struct PossibleState
26 {
27     uint16_t stateSetId;         //!< State set id
28     std::vector<uint8_t> states; //!< Possible states
29 };
30 
31 /** @struct DBusEffecterMapping
32  *  Contains the D-Bus information for an effecter
33  */
34 struct DBusEffecterMapping
35 {
36     pldm::utils::DBusMapping dbusMap;
37     std::vector<pldm::utils::PropertyValue>
38         propertyValues;  //!< D-Bus property values
39     PossibleState state; //!< Corresponding effecter states
40 };
41 
42 /** @struct EffecterInfo
43  *  Contains the effecter information as a whole
44  */
45 struct EffecterInfo
46 {
47     uint8_t mctpEid;         //!< Host mctp eid
48     uint16_t containerId;    //!< Container Id for host effecter
49     uint16_t entityType;     //!< Entity type for the host effecter
50     uint16_t entityInstance; //!< Entity instance for the host effecter
51     uint8_t compEffecterCnt; //!< Composite effecter count
52     std::vector<DBusEffecterMapping>
53         dbusInfo; //!< D-Bus information for the effecter id
54 };
55 
56 /** @class HostEffecterParser
57  *
58  *  @brief This class parses the Host Effecter json file and monitors for the
59  *         D-Bus changes for the effecters. Upon change, calls the corresponding
60  *         setStateEffecterStates on the host
61  */
62 class HostEffecterParser
63 {
64   public:
65     HostEffecterParser() = delete;
66     HostEffecterParser(const HostEffecterParser&) = delete;
67     HostEffecterParser& operator=(const HostEffecterParser&) = delete;
68     HostEffecterParser(HostEffecterParser&&) = delete;
69     HostEffecterParser& operator=(HostEffecterParser&&) = delete;
70     virtual ~HostEffecterParser() = default;
71 
72     /** @brief Constructor to create a HostEffecterParser object.
73      *  @param[in] requester - PLDM Requester object pointer
74      *  @param[in] fd - socket fd to communicate to host
75      *  @param[in] repo -  PLDM PDR repository
76      *  @param[in] dbusHandler - D-bus Handler
77      *  @param[in] jsonPath - path for the json file
78      *  @param[in] handler - PLDM request handler
79      */
80     explicit HostEffecterParser(
81         pldm::dbus_api::Requester* requester, int fd, const pldm_pdr* repo,
82         pldm::utils::DBusHandler* const dbusHandler,
83         const std::string& jsonPath,
84         pldm::requester::Handler<pldm::requester::Request>* handler) :
85         requester(requester),
86         sockFd(fd), pdrRepo(repo), dbusHandler(dbusHandler), handler(handler)
87     {
88         try
89         {
90             parseEffecterJson(jsonPath);
91         }
92         catch (const std::exception& e)
93         {
94             std::cerr << "The json file does not exist or malformed, ERROR="
95                       << e.what() << "\n";
96         }
97     }
98 
99     /* @brief Parses the host effecter json
100      *
101      * @param[in] jsonPath - path for the json file
102      */
103     void parseEffecterJson(const std::string& jsonPath);
104 
105     /* @brief Method to take action when the subscribed D-Bus property is
106      *        changed
107      * @param[in] chProperties - list of properties which have changed
108      * @param[in] effecterInfoIndex - index of effecterInfo pointer in
109      *                                hostEffecterInfo
110      * @param[in] dbusInfoIndex - index on dbusInfo pointer in each effecterInfo
111      * @param[in] effecterId - host effecter id
112      * @return - none
113      */
114     void processHostEffecterChangeNotification(
115         const DbusChgHostEffecterProps& chProperties, size_t effecterInfoIndex,
116         size_t dbusInfoIndex, uint16_t effecterId);
117 
118     /* @brief Populate the property values in each dbusInfo from the json
119      *
120      * @param[in] dBusValues - json values
121      * @param[out] propertyValues - dbusInfo property values
122      * @param[in] propertyType - type of the D-Bus property
123      * @return - none
124      */
125     void populatePropVals(
126         const pldm::utils::Json& dBusValues,
127         std::vector<pldm::utils::PropertyValue>& propertyValues,
128         const std::string& propertyType);
129 
130     /* @brief Set a host state effecter
131      *
132      * @param[in] effecterInfoIndex - index of effecterInfo pointer in
133      *                                hostEffecterInfo
134      * @param[in] stateField - vector of state fields equal to composite
135      *                         effecter count in number
136      * @param[in] effecterId - host effecter id
137      * @return - PLDM status code
138      */
139     virtual int
140         setHostStateEffecter(size_t effecterInfoIndex,
141                              std::vector<set_effecter_state_field>& stateField,
142                              uint16_t effecterId);
143 
144     /* @brief Fetches the new state value and the index in stateField set which
145      *        needs to be set with the new value in the setStateEffecter call
146      * @param[in] effecterInfoIndex - index of effecterInfo in hostEffecterInfo
147      * @param[in] dbusInfoIndex - index of dbusInfo within effecterInfo
148      * @param[in] propertyValue - the changed D-Bus property value
149      * @return - the new state value
150      */
151     uint8_t findNewStateValue(size_t effecterInfoIndex, size_t dbusInfoIndex,
152                               const pldm::utils::PropertyValue& propertyValue);
153 
154     /* @brief Subscribes for D-Bus property change signal on the specified
155      * object
156      *
157      * @param[in] objectPath - D-Bus object path to look for
158      * @param[in] interface - D-Bus interface
159      * @param[in] effecterInfoIndex - index of effecterInfo pointer in
160      *                                hostEffecterInfo
161      * @param[in] dbusInfoIndex - index of dbusInfo within effecterInfo
162      * @param[in] effecterId - host effecter id
163      */
164     virtual void createHostEffecterMatch(const std::string& objectPath,
165                                          const std::string& interface,
166                                          size_t effecterInfoIndex,
167                                          size_t dbusInfoIndex,
168                                          uint16_t effecterId);
169 
170   protected:
171     pldm::dbus_api::Requester*
172         requester;           //!< Reference to Requester to obtain instance id
173     int sockFd;              //!< Socket fd to send message to host
174     const pldm_pdr* pdrRepo; //!< Reference to PDR repo
175     std::vector<EffecterInfo> hostEffecterInfo; //!< Parsed effecter information
176     std::vector<std::unique_ptr<sdbusplus::bus::match::match>>
177         effecterInfoMatch; //!< vector to catch the D-Bus property change
178                            //!< signals for the effecters
179     const pldm::utils::DBusHandler* dbusHandler; //!< D-bus Handler
180     /** @brief PLDM request handler */
181     pldm::requester::Handler<pldm::requester::Request>* handler;
182 };
183 
184 } // namespace host_effecters
185 } // namespace pldm
186