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