1 #pragma once
2 
3 #include "common/types.hpp"
4 #include "common/utils.hpp"
5 #include "pldmd/dbus_impl_requester.hpp"
6 
7 #include <string>
8 #include <utility>
9 #include <vector>
10 
11 namespace pldm
12 {
13 
14 using namespace utils;
15 using namespace dbus_api;
16 
17 namespace host_effecters
18 {
19 
20 using DbusChgHostEffecterProps = std::map<dbus::Property, PropertyValue>;
21 
22 /** @struct State
23  *  Contains the state set id and the possible states for
24  *  an effecter
25  */
26 struct PossibleState
27 {
28     uint16_t stateSetId;         //!< State set id
29     std::vector<uint8_t> states; //!< Possible states
30 };
31 
32 /** @struct DBusEffecterMapping
33  *  Contains the D-Bus information for an effecter
34  */
35 struct DBusEffecterMapping
36 {
37     DBusMapping dbusMap;
38     std::vector<PropertyValue> 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] verbose - verbosity
79      */
80     explicit HostEffecterParser(Requester* requester, int fd,
81                                 const pldm_pdr* repo,
82                                 DBusHandler* const dbusHandler,
83                                 const std::string& jsonPath,
84                                 bool verbose = false) :
85         requester(requester),
86         sockFd(fd), pdrRepo(repo), dbusHandler(dbusHandler), verbose(verbose)
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(const Json& dBusValues,
126                           std::vector<PropertyValue>& propertyValues,
127                           const std::string& propertyType);
128 
129     /* @brief Set a host state effecter
130      *
131      * @param[in] effecterInfoIndex - index of effecterInfo pointer in
132      *                                hostEffecterInfo
133      * @param[in] stateField - vector of state fields equal to composite
134      *                         effecter count in number
135      * @param[in] effecterId - host effecter id
136      * @return - PLDM status code
137      */
138     virtual int
139         setHostStateEffecter(size_t effecterInfoIndex,
140                              std::vector<set_effecter_state_field>& stateField,
141                              uint16_t effecterId);
142 
143     /* @brief Fetches the new state value and the index in stateField set which
144      *        needs to be set with the new value in the setStateEffecter call
145      * @param[in] effecterInfoIndex - index of effecterInfo in hostEffecterInfo
146      * @param[in] dbusInfoIndex - index of dbusInfo within effecterInfo
147      * @param[in] propertyValue - the changed D-Bus property value
148      * @return - the new state value
149      */
150     uint8_t findNewStateValue(size_t effecterInfoIndex, size_t dbusInfoIndex,
151                               const PropertyValue& propertyValue);
152 
153     /* @brief Subscribes for D-Bus property change signal on the specified
154      * object
155      *
156      * @param[in] objectPath - D-Bus object path to look for
157      * @param[in] interface - D-Bus interface
158      * @param[in] effecterInfoIndex - index of effecterInfo pointer in
159      *                                hostEffecterInfo
160      * @param[in] dbusInfoIndex - index of dbusInfo within effecterInfo
161      * @param[in] effecterId - host effecter id
162      */
163     virtual void createHostEffecterMatch(const std::string& objectPath,
164                                          const std::string& interface,
165                                          size_t effecterInfoIndex,
166                                          size_t dbusInfoIndex,
167                                          uint16_t effecterId);
168 
169   protected:
170     Requester* requester;    //!< Reference to Requester to obtain instance id
171     int sockFd;              //!< Socket fd to send message to host
172     const pldm_pdr* pdrRepo; //!< Reference to PDR repo
173     std::vector<EffecterInfo> hostEffecterInfo; //!< Parsed effecter information
174     std::vector<std::unique_ptr<sdbusplus::bus::match::match>>
175         effecterInfoMatch; //!< vector to catch the D-Bus property change
176                            //!< signals for the effecters
177     const DBusHandler* dbusHandler; //!< D-bus Handler
178     bool verbose;                   //!< verbose flag
179 };
180 
181 } // namespace host_effecters
182 } // namespace pldm
183