blob: ae081562c527630660add954023777f7a3dd25a6 [file] [log] [blame]
Lei YU5e0dcb32019-08-02 18:04:34 +08001#pragma once
2
Lei YU4b9ac392019-10-12 11:02:26 +08003#include "types.hpp"
4
Lei YUf77189f2019-08-07 14:26:30 +08005#include <experimental/any>
Lei YU5e0dcb32019-08-02 18:04:34 +08006#include <sdbusplus/bus.hpp>
Lei YU65207482019-10-11 16:39:36 +08007#include <set>
Lei YU5e0dcb32019-08-02 18:04:34 +08008#include <string>
9#include <vector>
10
11namespace utils
12{
13
Lei YUf77189f2019-08-07 14:26:30 +080014class UtilsInterface;
15
Lei YU4b9ac392019-10-12 11:02:26 +080016using AssociationList = phosphor::software::updater::AssociationList;
Lei YUf77189f2019-08-07 14:26:30 +080017// Due to a libstdc++ bug, we got compile error using std::any with gmock.
18// A temporary workaround is to use std::experimental::any.
19// See details in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90415
20using std::experimental::any;
21using std::experimental::any_cast;
22
23/**
24 * @brief Get the implementation of UtilsInterface
25 */
26const UtilsInterface& getUtils();
Lei YUad90ad52019-08-06 11:19:28 +080027
Lei YU5e0dcb32019-08-02 18:04:34 +080028/**
29 * @brief Get PSU inventory object path from DBus
30 */
31std::vector<std::string> getPSUInventoryPath(sdbusplus::bus::bus& bus);
32
Lei YUad90ad52019-08-06 11:19:28 +080033/** @brief Get service name from object path and interface
34 *
35 * @param[in] bus - The Dbus bus object
36 * @param[in] path - The Dbus object path
37 * @param[in] interface - The Dbus interface
38 *
39 * @return The name of the service
40 */
41std::string getService(sdbusplus::bus::bus& bus, const char* path,
42 const char* interface);
43
Lei YUd0bbfa92019-09-11 16:10:54 +080044/** @brief Get all the service names from object path and interface
45 *
46 * @param[in] bus - The Dbus bus object
47 * @param[in] path - The Dbus object path
48 * @param[in] interface - The Dbus interface
49 *
50 * @return The name of the services
51 */
52std::vector<std::string> getServices(sdbusplus::bus::bus& bus, const char* path,
53 const char* interface);
54
Lei YUad90ad52019-08-06 11:19:28 +080055/** @brief The template function to get property from the requested dbus path
56 *
57 * @param[in] bus - The Dbus bus object
58 * @param[in] service - The Dbus service name
59 * @param[in] path - The Dbus object path
60 * @param[in] interface - The Dbus interface
61 * @param[in] propertyName - The property name to get
62 *
63 * @return The value of the property
64 */
65template <typename T>
66T getProperty(sdbusplus::bus::bus& bus, const char* service, const char* path,
Lei YUf77189f2019-08-07 14:26:30 +080067 const char* interface, const char* propertyName);
Lei YUad90ad52019-08-06 11:19:28 +080068
69/**
70 * @brief Calculate the version id from the version string.
71 *
72 * @details The version id is a unique 8 hexadecimal digit id
73 * calculated from the version string.
74 *
75 * @param[in] version - The image version string (e.g. v1.99.10-19).
76 *
77 * @return The id.
78 */
79std::string getVersionId(const std::string& version);
80
Lei YU5f3584d2019-08-27 16:28:53 +080081/** @brief Get version of PSU specified by the inventory path
82 *
83 * @param[in] inventoryPath - The PSU inventory object path
84 *
85 * @return The version string, or empry string if it fails to get the version
86 */
87std::string getVersion(const std::string& inventoryPath);
88
Lei YU65207482019-10-11 16:39:36 +080089/** @brief Get latest version from the PSU versions
90 *
91 * @param[in] versions - The list of the versions
92 *
93 * @return The latest version string
94 */
95std::string getLatestVersion(const std::set<std::string>& versions);
96
Lei YU4b9ac392019-10-12 11:02:26 +080097/** @brief Check if the PSU is associated
98 *
99 * @param[in] psuInventoryPath - The PSU inventory path
100 * @param[in] assocs - The list of associations
101 *
102 * @return true if the psu is in the association list
103 */
104bool isAssociated(const std::string& psuInventoryPath,
105 const AssociationList& assocs);
106
Lei YUf77189f2019-08-07 14:26:30 +0800107/**
108 * @brief The interface for utils
109 */
110class UtilsInterface
111{
112 public:
113 // For now the code needs to get property for Present and Version
114 using PropertyType = sdbusplus::message::variant<std::string, bool>;
115
116 virtual ~UtilsInterface() = default;
117
118 virtual std::vector<std::string>
119 getPSUInventoryPath(sdbusplus::bus::bus& bus) const = 0;
120
121 virtual std::string getService(sdbusplus::bus::bus& bus, const char* path,
122 const char* interface) const = 0;
123
Lei YUd0bbfa92019-09-11 16:10:54 +0800124 virtual std::vector<std::string>
125 getServices(sdbusplus::bus::bus& bus, const char* path,
126 const char* interface) const = 0;
127
Lei YUf77189f2019-08-07 14:26:30 +0800128 virtual std::string getVersionId(const std::string& version) const = 0;
129
Lei YU5f3584d2019-08-27 16:28:53 +0800130 virtual std::string getVersion(const std::string& inventoryPath) const = 0;
131
Lei YU65207482019-10-11 16:39:36 +0800132 virtual std::string
133 getLatestVersion(const std::set<std::string>& versions) const = 0;
134
Lei YU4b9ac392019-10-12 11:02:26 +0800135 virtual bool isAssociated(const std::string& psuInventoryPath,
136 const AssociationList& assocs) const = 0;
137
Lei YUf77189f2019-08-07 14:26:30 +0800138 virtual any getPropertyImpl(sdbusplus::bus::bus& bus, const char* service,
139 const char* path, const char* interface,
140 const char* propertyName) const = 0;
141
142 template <typename T>
143 T getProperty(sdbusplus::bus::bus& bus, const char* service,
144 const char* path, const char* interface,
145 const char* propertyName) const
146 {
147 any result =
148 getPropertyImpl(bus, service, path, interface, propertyName);
149 auto value = any_cast<PropertyType>(result);
150 return sdbusplus::message::variant_ns::get<T>(value);
151 }
152};
153
154class Utils : public UtilsInterface
155{
156 public:
157 std::vector<std::string>
158 getPSUInventoryPath(sdbusplus::bus::bus& bus) const override;
159
160 std::string getService(sdbusplus::bus::bus& bus, const char* path,
161 const char* interface) const override;
162
Lei YUd0bbfa92019-09-11 16:10:54 +0800163 std::vector<std::string> getServices(sdbusplus::bus::bus& bus,
164 const char* path,
165 const char* interface) const override;
166
Lei YUf77189f2019-08-07 14:26:30 +0800167 std::string getVersionId(const std::string& version) const override;
168
Lei YU5f3584d2019-08-27 16:28:53 +0800169 std::string getVersion(const std::string& inventoryPath) const override;
170
Lei YU65207482019-10-11 16:39:36 +0800171 std::string
172 getLatestVersion(const std::set<std::string>& versions) const override;
173
Lei YU4b9ac392019-10-12 11:02:26 +0800174 bool isAssociated(const std::string& psuInventoryPath,
175 const AssociationList& assocs) const override;
176
Lei YUf77189f2019-08-07 14:26:30 +0800177 any getPropertyImpl(sdbusplus::bus::bus& bus, const char* service,
178 const char* path, const char* interface,
179 const char* propertyName) const override;
180};
181
182inline std::string getService(sdbusplus::bus::bus& bus, const char* path,
183 const char* interface)
184{
185 return getUtils().getService(bus, path, interface);
186}
187
Lei YUd0bbfa92019-09-11 16:10:54 +0800188inline std::vector<std::string> getServices(sdbusplus::bus::bus& bus,
189 const char* path,
190 const char* interface)
191{
192 return getUtils().getServices(bus, path, interface);
193}
194
Lei YUf77189f2019-08-07 14:26:30 +0800195inline std::vector<std::string> getPSUInventoryPath(sdbusplus::bus::bus& bus)
196{
197 return getUtils().getPSUInventoryPath(bus);
198}
199
200inline std::string getVersionId(const std::string& version)
201{
202 return getUtils().getVersionId(version);
203}
204
Lei YU5f3584d2019-08-27 16:28:53 +0800205inline std::string getVersion(const std::string& inventoryPath)
206{
207 return getUtils().getVersion(inventoryPath);
208}
209
Lei YU65207482019-10-11 16:39:36 +0800210inline std::string getLatestVersion(const std::set<std::string>& versions)
211{
212 return getUtils().getLatestVersion(versions);
213}
214
Lei YU4b9ac392019-10-12 11:02:26 +0800215inline bool isAssociated(const std::string& psuInventoryPath,
216 const AssociationList& assocs)
217{
218 return getUtils().isAssociated(psuInventoryPath, assocs);
219}
220
Lei YUf77189f2019-08-07 14:26:30 +0800221template <typename T>
222T getProperty(sdbusplus::bus::bus& bus, const char* service, const char* path,
223 const char* interface, const char* propertyName)
224{
225 return getUtils().getProperty<T>(bus, service, path, interface,
226 propertyName);
227}
228
Lei YU5e0dcb32019-08-02 18:04:34 +0800229} // namespace utils