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