1 #pragma once 2 3 #include <experimental/any> 4 #include <sdbusplus/bus.hpp> 5 #include <set> 6 #include <string> 7 #include <vector> 8 9 namespace utils 10 { 11 12 class UtilsInterface; 13 14 // Due to a libstdc++ bug, we got compile error using std::any with gmock. 15 // A temporary workaround is to use std::experimental::any. 16 // See details in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90415 17 using std::experimental::any; 18 using std::experimental::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::bus& 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::bus& 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::bus& 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::bus& 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 /** 95 * @brief The interface for utils 96 */ 97 class UtilsInterface 98 { 99 public: 100 // For now the code needs to get property for Present and Version 101 using PropertyType = sdbusplus::message::variant<std::string, bool>; 102 103 virtual ~UtilsInterface() = default; 104 105 virtual std::vector<std::string> 106 getPSUInventoryPath(sdbusplus::bus::bus& bus) const = 0; 107 108 virtual std::string getService(sdbusplus::bus::bus& bus, const char* path, 109 const char* interface) const = 0; 110 111 virtual std::vector<std::string> 112 getServices(sdbusplus::bus::bus& bus, const char* path, 113 const char* interface) const = 0; 114 115 virtual std::string getVersionId(const std::string& version) const = 0; 116 117 virtual std::string getVersion(const std::string& inventoryPath) const = 0; 118 119 virtual std::string 120 getLatestVersion(const std::set<std::string>& versions) const = 0; 121 122 virtual any getPropertyImpl(sdbusplus::bus::bus& bus, const char* service, 123 const char* path, const char* interface, 124 const char* propertyName) const = 0; 125 126 template <typename T> 127 T getProperty(sdbusplus::bus::bus& bus, const char* service, 128 const char* path, const char* interface, 129 const char* propertyName) const 130 { 131 any result = 132 getPropertyImpl(bus, service, path, interface, propertyName); 133 auto value = any_cast<PropertyType>(result); 134 return sdbusplus::message::variant_ns::get<T>(value); 135 } 136 }; 137 138 class Utils : public UtilsInterface 139 { 140 public: 141 std::vector<std::string> 142 getPSUInventoryPath(sdbusplus::bus::bus& bus) const override; 143 144 std::string getService(sdbusplus::bus::bus& bus, const char* path, 145 const char* interface) const override; 146 147 std::vector<std::string> getServices(sdbusplus::bus::bus& bus, 148 const char* path, 149 const char* interface) const override; 150 151 std::string getVersionId(const std::string& version) const override; 152 153 std::string getVersion(const std::string& inventoryPath) const override; 154 155 std::string 156 getLatestVersion(const std::set<std::string>& versions) const override; 157 158 any getPropertyImpl(sdbusplus::bus::bus& bus, const char* service, 159 const char* path, const char* interface, 160 const char* propertyName) const override; 161 }; 162 163 inline std::string getService(sdbusplus::bus::bus& bus, const char* path, 164 const char* interface) 165 { 166 return getUtils().getService(bus, path, interface); 167 } 168 169 inline std::vector<std::string> getServices(sdbusplus::bus::bus& bus, 170 const char* path, 171 const char* interface) 172 { 173 return getUtils().getServices(bus, path, interface); 174 } 175 176 inline std::vector<std::string> getPSUInventoryPath(sdbusplus::bus::bus& bus) 177 { 178 return getUtils().getPSUInventoryPath(bus); 179 } 180 181 inline std::string getVersionId(const std::string& version) 182 { 183 return getUtils().getVersionId(version); 184 } 185 186 inline std::string getVersion(const std::string& inventoryPath) 187 { 188 return getUtils().getVersion(inventoryPath); 189 } 190 191 inline std::string getLatestVersion(const std::set<std::string>& versions) 192 { 193 return getUtils().getLatestVersion(versions); 194 } 195 196 template <typename T> 197 T getProperty(sdbusplus::bus::bus& bus, const char* service, const char* path, 198 const char* interface, const char* propertyName) 199 { 200 return getUtils().getProperty<T>(bus, service, path, interface, 201 propertyName); 202 } 203 204 } // namespace utils 205