1 #pragma once 2 3 #include "types.hpp" 4 5 #include <experimental/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 // 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 20 using std::experimental::any; 21 using std::experimental::any_cast; 22 23 /** 24 * @brief Get the implementation of UtilsInterface 25 */ 26 const UtilsInterface& getUtils(); 27 28 /** 29 * @brief Get PSU inventory object path from DBus 30 */ 31 std::vector<std::string> getPSUInventoryPath(sdbusplus::bus::bus& bus); 32 33 /** @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 */ 41 std::string getService(sdbusplus::bus::bus& bus, const char* path, 42 const char* interface); 43 44 /** @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 */ 52 std::vector<std::string> getServices(sdbusplus::bus::bus& bus, const char* path, 53 const char* interface); 54 55 /** @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 */ 65 template <typename T> 66 T getProperty(sdbusplus::bus::bus& bus, const char* service, const char* path, 67 const char* interface, const char* propertyName); 68 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 */ 79 std::string getVersionId(const std::string& version); 80 81 /** @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 */ 87 std::string getVersion(const std::string& inventoryPath); 88 89 /** @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 */ 95 std::string getLatestVersion(const std::set<std::string>& versions); 96 97 /** @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 */ 104 bool isAssociated(const std::string& psuInventoryPath, 105 const AssociationList& assocs); 106 107 /** 108 * @brief The interface for utils 109 */ 110 class 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 124 virtual std::vector<std::string> 125 getServices(sdbusplus::bus::bus& bus, const char* path, 126 const char* interface) const = 0; 127 128 virtual std::string getVersionId(const std::string& version) const = 0; 129 130 virtual std::string getVersion(const std::string& inventoryPath) const = 0; 131 132 virtual std::string 133 getLatestVersion(const std::set<std::string>& versions) const = 0; 134 135 virtual bool isAssociated(const std::string& psuInventoryPath, 136 const AssociationList& assocs) const = 0; 137 138 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 154 class 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 163 std::vector<std::string> getServices(sdbusplus::bus::bus& bus, 164 const char* path, 165 const char* interface) const override; 166 167 std::string getVersionId(const std::string& version) const override; 168 169 std::string getVersion(const std::string& inventoryPath) const override; 170 171 std::string 172 getLatestVersion(const std::set<std::string>& versions) const override; 173 174 bool isAssociated(const std::string& psuInventoryPath, 175 const AssociationList& assocs) const override; 176 177 any getPropertyImpl(sdbusplus::bus::bus& bus, const char* service, 178 const char* path, const char* interface, 179 const char* propertyName) const override; 180 }; 181 182 inline std::string getService(sdbusplus::bus::bus& bus, const char* path, 183 const char* interface) 184 { 185 return getUtils().getService(bus, path, interface); 186 } 187 188 inline 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 195 inline std::vector<std::string> getPSUInventoryPath(sdbusplus::bus::bus& bus) 196 { 197 return getUtils().getPSUInventoryPath(bus); 198 } 199 200 inline std::string getVersionId(const std::string& version) 201 { 202 return getUtils().getVersionId(version); 203 } 204 205 inline std::string getVersion(const std::string& inventoryPath) 206 { 207 return getUtils().getVersion(inventoryPath); 208 } 209 210 inline std::string getLatestVersion(const std::set<std::string>& versions) 211 { 212 return getUtils().getLatestVersion(versions); 213 } 214 215 inline bool isAssociated(const std::string& psuInventoryPath, 216 const AssociationList& assocs) 217 { 218 return getUtils().isAssociated(psuInventoryPath, assocs); 219 } 220 221 template <typename T> 222 T 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 229 } // namespace utils 230