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 path from DBus
28 */
29 std::vector<std::string> getPSUInventoryPath(sdbusplus::bus_t& bus);
30
31 /** @brief Get service name from object path and interface
32 *
33 * @param[in] bus - The Dbus bus object
34 * @param[in] path - The Dbus object path
35 * @param[in] interface - The Dbus interface
36 *
37 * @return The name of the service
38 */
39 std::string getService(sdbusplus::bus_t& bus, const char* path,
40 const char* interface);
41
42 /** @brief Get all the service names from object path and interface
43 *
44 * @param[in] bus - The Dbus bus object
45 * @param[in] path - The Dbus object path
46 * @param[in] interface - The Dbus interface
47 *
48 * @return The name of the services
49 */
50 std::vector<std::string> getServices(sdbusplus::bus_t& bus, const char* path,
51 const char* interface);
52
53 /** @brief The template function to get property from the requested dbus path
54 *
55 * @param[in] bus - The Dbus bus object
56 * @param[in] service - The Dbus service name
57 * @param[in] path - The Dbus object path
58 * @param[in] interface - The Dbus interface
59 * @param[in] propertyName - The property name to get
60 *
61 * @return The value of the property
62 */
63 template <typename T>
64 T getProperty(sdbusplus::bus_t& bus, const char* service, const char* path,
65 const char* interface, const char* propertyName);
66
67 /**
68 * @brief Calculate the version id from the version string.
69 *
70 * @details The version id is a unique 8 hexadecimal digit id
71 * calculated from the version string.
72 *
73 * @param[in] version - The image version string (e.g. v1.99.10-19).
74 *
75 * @return The id.
76 */
77 std::string getVersionId(const std::string& version);
78
79 /** @brief Get version of PSU specified by the inventory path
80 *
81 * @param[in] inventoryPath - The PSU inventory object path
82 *
83 * @return The version string, or empry string if it fails to get the version
84 */
85 std::string getVersion(const std::string& inventoryPath);
86
87 /** @brief Get latest version from the PSU versions
88 *
89 * @param[in] versions - The list of the versions
90 *
91 * @return The latest version string
92 */
93 std::string getLatestVersion(const std::set<std::string>& versions);
94
95 /** @brief Check if the PSU is associated
96 *
97 * @param[in] psuInventoryPath - The PSU inventory path
98 * @param[in] assocs - The list of associations
99 *
100 * @return true if the psu is in the association list
101 */
102 bool isAssociated(const std::string& psuInventoryPath,
103 const AssociationList& assocs);
104
105 /**
106 * @brief The interface for utils
107 */
108 class UtilsInterface
109 {
110 public:
111 UtilsInterface() = default;
112 UtilsInterface(const UtilsInterface&) = delete;
113 UtilsInterface& operator=(const UtilsInterface&) = delete;
114 UtilsInterface(UtilsInterface&&) = delete;
115 UtilsInterface& operator=(UtilsInterface&&) = delete;
116
117 // For now the code needs to get property for Present and Version
118 using PropertyType = std::variant<std::string, bool>;
119
120 virtual ~UtilsInterface() = default;
121
122 virtual std::vector<std::string>
123 getPSUInventoryPath(sdbusplus::bus_t& bus) const = 0;
124
125 virtual std::string getService(sdbusplus::bus_t& bus, const char* path,
126 const char* interface) const = 0;
127
128 virtual std::vector<std::string>
129 getServices(sdbusplus::bus_t& bus, const char* path,
130 const char* interface) const = 0;
131
132 virtual std::string getVersionId(const std::string& version) const = 0;
133
134 virtual std::string getVersion(const std::string& inventoryPath) const = 0;
135
136 virtual std::string
137 getLatestVersion(const std::set<std::string>& versions) const = 0;
138
139 virtual bool isAssociated(const std::string& psuInventoryPath,
140 const AssociationList& assocs) const = 0;
141
142 virtual any getPropertyImpl(sdbusplus::bus_t& bus, const char* service,
143 const char* path, const char* interface,
144 const char* propertyName) const = 0;
145
146 template <typename T>
getProperty(sdbusplus::bus_t & bus,const char * service,const char * path,const char * interface,const char * propertyName) const147 T getProperty(sdbusplus::bus_t& bus, const char* service, const char* path,
148 const char* interface, const char* propertyName) const
149 {
150 any result =
151 getPropertyImpl(bus, service, path, interface, propertyName);
152 auto value = any_cast<PropertyType>(result);
153 return std::get<T>(value);
154 }
155 };
156
157 class Utils : public UtilsInterface
158 {
159 public:
160 std::vector<std::string>
161 getPSUInventoryPath(sdbusplus::bus_t& bus) const override;
162
163 std::string getService(sdbusplus::bus_t& bus, const char* path,
164 const char* interface) const override;
165
166 std::vector<std::string> getServices(sdbusplus::bus_t& bus,
167 const char* path,
168 const char* interface) const override;
169
170 std::string getVersionId(const std::string& version) const override;
171
172 std::string getVersion(const std::string& inventoryPath) const override;
173
174 std::string
175 getLatestVersion(const std::set<std::string>& versions) const override;
176
177 bool isAssociated(const std::string& psuInventoryPath,
178 const AssociationList& assocs) const override;
179
180 any getPropertyImpl(sdbusplus::bus_t& bus, const char* service,
181 const char* path, const char* interface,
182 const char* propertyName) const override;
183 };
184
getService(sdbusplus::bus_t & bus,const char * path,const char * interface)185 inline std::string getService(sdbusplus::bus_t& bus, const char* path,
186 const char* interface)
187 {
188 return getUtils().getService(bus, path, interface);
189 }
190
191 inline std::vector<std::string>
getServices(sdbusplus::bus_t & bus,const char * path,const char * interface)192 getServices(sdbusplus::bus_t& bus, const char* path, const char* interface)
193 {
194 return getUtils().getServices(bus, path, interface);
195 }
196
getPSUInventoryPath(sdbusplus::bus_t & bus)197 inline std::vector<std::string> getPSUInventoryPath(sdbusplus::bus_t& bus)
198 {
199 return getUtils().getPSUInventoryPath(bus);
200 }
201
getVersionId(const std::string & version)202 inline std::string getVersionId(const std::string& version)
203 {
204 return getUtils().getVersionId(version);
205 }
206
getVersion(const std::string & inventoryPath)207 inline std::string getVersion(const std::string& inventoryPath)
208 {
209 return getUtils().getVersion(inventoryPath);
210 }
211
getLatestVersion(const std::set<std::string> & versions)212 inline std::string getLatestVersion(const std::set<std::string>& versions)
213 {
214 return getUtils().getLatestVersion(versions);
215 }
216
isAssociated(const std::string & psuInventoryPath,const AssociationList & assocs)217 inline bool isAssociated(const std::string& psuInventoryPath,
218 const AssociationList& assocs)
219 {
220 return getUtils().isAssociated(psuInventoryPath, assocs);
221 }
222
223 template <typename T>
getProperty(sdbusplus::bus_t & bus,const char * service,const char * path,const char * interface,const char * propertyName)224 T getProperty(sdbusplus::bus_t& bus, const char* service, const char* path,
225 const char* interface, const char* propertyName)
226 {
227 return getUtils().getProperty<T>(bus, service, path, interface,
228 propertyName);
229 }
230
231 } // namespace utils
232