xref: /openbmc/phosphor-psu-code-mgmt/src/utils.hpp (revision 638b84ae544defb76091053652042e19adfd2f53)
1 #pragma once
2 
3 #include "types.hpp"
4 
5 #include <sdbusplus/bus.hpp>
6 
7 #include <any>
8 #include <set>
9 #include <string>
10 #include <vector>
11 
12 namespace utils
13 {
14 
15 class UtilsInterface;
16 
17 using AssociationList = phosphor::software::updater::AssociationList;
18 using std::any;
19 using std::any_cast;
20 
21 /**
22  * @brief Get the implementation of UtilsInterface
23  */
24 const UtilsInterface& getUtils();
25 
26 /**
27  * @brief Get PSU inventory object paths from DBus
28  *
29  * @details The returned vector will be empty if an error occurs or no paths are
30  *          found.
31  *
32  * @param[in] bus - The Dbus bus object
33  *
34  * @return PSU inventory object paths that were found (if any)
35  */
36 std::vector<std::string> getPSUInventoryPaths(sdbusplus::bus_t& bus);
37 
38 /** @brief Get service name from object path and interface
39  *
40  *  @details Throws an exception if an error occurs or no service name was
41  *           found.
42  *
43  * @param[in] bus          - The Dbus bus object
44  * @param[in] path         - The Dbus object path
45  * @param[in] interface    - The Dbus interface
46  *
47  * @return The name of the service
48  */
49 std::string getService(sdbusplus::bus_t& bus, const char* path,
50                        const char* interface);
51 
52 /** @brief Get all service names from object path and interface
53  *
54  *  @details The returned vector will be empty if no service names were found.
55  *           Throws an exception if an error occurs.
56  *
57  * @param[in] bus          - The Dbus bus object
58  * @param[in] path         - The Dbus object path
59  * @param[in] interface    - The Dbus interface
60  *
61  * @return The name of the services (if any)
62  */
63 std::vector<std::string> getServices(sdbusplus::bus_t& bus, const char* path,
64                                      const char* interface);
65 
66 /** @brief The template function to get property from the requested dbus path
67  *
68  *  @details Throws an exception if an error occurs
69  *
70  * @param[in] bus          - The Dbus bus object
71  * @param[in] service      - The Dbus service name
72  * @param[in] path         - The Dbus object path
73  * @param[in] interface    - The Dbus interface
74  * @param[in] propertyName - The property name to get
75  *
76  * @return The value of the property
77  */
78 template <typename T>
79 T getProperty(sdbusplus::bus_t& bus, const char* service, const char* path,
80               const char* interface, const char* propertyName);
81 
82 /**
83  * @brief Calculate the version id from the version string.
84  *
85  * @details The version id is a unique 8 hexadecimal digit id
86  *          calculated from the version string.
87  *
88  * @param[in] version - The image version string (e.g. v1.99.10-19).
89  *
90  * @return The id.
91  */
92 std::string getVersionId(const std::string& version);
93 
94 /** @brief Get version of PSU specified by the inventory path
95  *
96  * @param[in] inventoryPath - The PSU inventory object path
97  *
98  * @return The version string, or empty string if it fails to get the version
99  */
100 std::string getVersion(const std::string& inventoryPath);
101 
102 /** @brief Get model of PSU specified by the inventory path
103  *
104  * @param[in] inventoryPath - The PSU inventory object path
105  *
106  * @return The model string, or empty string if it fails to get the model
107  */
108 std::string getModel(const std::string& inventoryPath);
109 
110 /** @brief Get latest version from the PSU versions
111  *
112  * @param[in] versions - The list of the versions
113  *
114  * @return The latest version string, or empty string if it fails to get the
115  *         latest version
116  */
117 std::string getLatestVersion(const std::set<std::string>& versions);
118 
119 /** @brief Check if the PSU is associated
120  *
121  * @param[in] psuInventoryPath - The PSU inventory path
122  * @param[in] assocs - The list of associations
123  *
124  * @return true if the psu is in the association list
125  */
126 bool isAssociated(const std::string& psuInventoryPath,
127                   const AssociationList& assocs);
128 
129 /**
130  * @brief The interface for utils
131  */
132 class UtilsInterface
133 {
134   public:
135     UtilsInterface() = default;
136     UtilsInterface(const UtilsInterface&) = delete;
137     UtilsInterface& operator=(const UtilsInterface&) = delete;
138     UtilsInterface(UtilsInterface&&) = delete;
139     UtilsInterface& operator=(UtilsInterface&&) = delete;
140 
141     // For now the code needs to get property for Present and Version
142     using PropertyType = std::variant<std::string, bool>;
143 
144     virtual ~UtilsInterface() = default;
145 
146     virtual std::vector<std::string> getPSUInventoryPaths(
147         sdbusplus::bus_t& bus) const = 0;
148 
149     virtual std::string getService(sdbusplus::bus_t& bus, const char* path,
150                                    const char* interface) const = 0;
151 
152     virtual std::vector<std::string> getServices(
153         sdbusplus::bus_t& bus, const char* path,
154         const char* interface) const = 0;
155 
156     virtual std::string getVersionId(const std::string& version) const = 0;
157 
158     virtual std::string getVersion(const std::string& inventoryPath) const = 0;
159 
160     virtual std::string getModel(const std::string& inventoryPath) const = 0;
161 
162     virtual std::string getLatestVersion(
163         const std::set<std::string>& versions) const = 0;
164 
165     virtual bool isAssociated(const std::string& psuInventoryPath,
166                               const AssociationList& assocs) const = 0;
167 
168     virtual any getPropertyImpl(sdbusplus::bus_t& bus, const char* service,
169                                 const char* path, const char* interface,
170                                 const char* propertyName) const = 0;
171 
172     template <typename T>
getProperty(sdbusplus::bus_t & bus,const char * service,const char * path,const char * interface,const char * propertyName) const173     T getProperty(sdbusplus::bus_t& bus, const char* service, const char* path,
174                   const char* interface, const char* propertyName) const
175     {
176         any result =
177             getPropertyImpl(bus, service, path, interface, propertyName);
178         auto value = any_cast<PropertyType>(result);
179         return std::get<T>(value);
180     }
181 };
182 
183 class Utils : public UtilsInterface
184 {
185   public:
186     std::vector<std::string> getPSUInventoryPaths(
187         sdbusplus::bus_t& bus) const override;
188 
189     std::string getService(sdbusplus::bus_t& bus, const char* path,
190                            const char* interface) const override;
191 
192     std::vector<std::string> getServices(sdbusplus::bus_t& bus,
193                                          const char* path,
194                                          const char* interface) const override;
195 
196     std::string getVersionId(const std::string& version) const override;
197 
198     std::string getVersion(const std::string& inventoryPath) const override;
199 
200     std::string getModel(const std::string& inventoryPath) const override;
201 
202     std::string getLatestVersion(
203         const std::set<std::string>& versions) const override;
204 
205     bool isAssociated(const std::string& psuInventoryPath,
206                       const AssociationList& assocs) const override;
207 
208     any getPropertyImpl(sdbusplus::bus_t& bus, const char* service,
209                         const char* path, const char* interface,
210                         const char* propertyName) const override;
211 };
212 
getService(sdbusplus::bus_t & bus,const char * path,const char * interface)213 inline std::string getService(sdbusplus::bus_t& bus, const char* path,
214                               const char* interface)
215 {
216     return getUtils().getService(bus, path, interface);
217 }
218 
getServices(sdbusplus::bus_t & bus,const char * path,const char * interface)219 inline std::vector<std::string> getServices(
220     sdbusplus::bus_t& bus, const char* path, const char* interface)
221 {
222     return getUtils().getServices(bus, path, interface);
223 }
224 
getPSUInventoryPaths(sdbusplus::bus_t & bus)225 inline std::vector<std::string> getPSUInventoryPaths(sdbusplus::bus_t& bus)
226 {
227     return getUtils().getPSUInventoryPaths(bus);
228 }
229 
getVersionId(const std::string & version)230 inline std::string getVersionId(const std::string& version)
231 {
232     return getUtils().getVersionId(version);
233 }
234 
getVersion(const std::string & inventoryPath)235 inline std::string getVersion(const std::string& inventoryPath)
236 {
237     return getUtils().getVersion(inventoryPath);
238 }
239 
getModel(const std::string & inventoryPath)240 inline std::string getModel(const std::string& inventoryPath)
241 {
242     return getUtils().getModel(inventoryPath);
243 }
244 
getLatestVersion(const std::set<std::string> & versions)245 inline std::string getLatestVersion(const std::set<std::string>& versions)
246 {
247     return getUtils().getLatestVersion(versions);
248 }
249 
isAssociated(const std::string & psuInventoryPath,const AssociationList & assocs)250 inline bool isAssociated(const std::string& psuInventoryPath,
251                          const AssociationList& assocs)
252 {
253     return getUtils().isAssociated(psuInventoryPath, assocs);
254 }
255 
256 template <typename T>
getProperty(sdbusplus::bus_t & bus,const char * service,const char * path,const char * interface,const char * propertyName)257 T getProperty(sdbusplus::bus_t& bus, const char* service, const char* path,
258               const char* interface, const char* propertyName)
259 {
260     return getUtils().getProperty<T>(bus, service, path, interface,
261                                      propertyName);
262 }
263 
264 } // namespace utils
265