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