1 #pragma once 2 3 #include "pmbus.hpp" 4 5 #include <nlohmann/json.hpp> 6 #include <phosphor-logging/elog.hpp> 7 #include <phosphor-logging/lg2.hpp> 8 #include <sdbusplus/bus.hpp> 9 10 #include <string> 11 #include <vector> 12 13 namespace phosphor 14 { 15 namespace power 16 { 17 namespace util 18 { 19 20 constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1"; 21 constexpr auto SYSTEMD_ROOT = "/org/freedesktop/systemd1"; 22 constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager"; 23 constexpr auto POWEROFF_TARGET = "obmc-chassis-hard-poweroff@0.target"; 24 constexpr auto PROPERTY_INTF = "org.freedesktop.DBus.Properties"; 25 constexpr auto ENTITY_MGR_SERVICE = "xyz.openbmc_project.EntityManager"; 26 27 using DbusPath = std::string; 28 using DbusProperty = std::string; 29 using DbusService = std::string; 30 using DbusInterface = std::string; 31 using DbusInterfaceList = std::vector<DbusInterface>; 32 using DbusSubtree = 33 std::map<DbusPath, std::map<DbusService, DbusInterfaceList>>; 34 using DbusVariant = 35 std::variant<bool, uint64_t, std::string, std::vector<uint64_t>, 36 std::vector<std::string>>; 37 using DbusPropertyMap = std::map<DbusProperty, DbusVariant>; 38 /** 39 * @brief Get the service name from the mapper for the 40 * interface and path passed in. 41 * 42 * @param[in] path - the D-Bus path name 43 * @param[in] interface - the D-Bus interface name 44 * @param[in] bus - the D-Bus object 45 * @param[in] logError - log error when no service found 46 * 47 * @return The service name 48 */ 49 std::string getService(const std::string& path, const std::string& interface, 50 sdbusplus::bus_t& bus, bool logError = true); 51 52 /** 53 * @brief Read a D-Bus property 54 * 55 * @param[in] interface - the interface the property is on 56 * @param[in] propertName - the name of the property 57 * @param[in] path - the D-Bus path 58 * @param[in] service - the D-Bus service 59 * @param[in] bus - the D-Bus object 60 * @param[out] value - filled in with the property value 61 */ 62 template <typename T> 63 void getProperty(const std::string& interface, const std::string& propertyName, 64 const std::string& path, const std::string& service, 65 sdbusplus::bus_t& bus, T& value) 66 { 67 std::variant<T> property; 68 69 auto method = bus.new_method_call(service.c_str(), path.c_str(), 70 PROPERTY_INTF, "Get"); 71 72 method.append(interface, propertyName); 73 74 auto reply = bus.call(method); 75 76 reply.read(property); 77 value = std::get<T>(property); 78 } 79 80 /** 81 * @brief Write a D-Bus property 82 * 83 * @param[in] interface - the interface the property is on 84 * @param[in] propertName - the name of the property 85 * @param[in] path - the D-Bus path 86 * @param[in] service - the D-Bus service 87 * @param[in] bus - the D-Bus object 88 * @param[in] value - the value to set the property to 89 */ 90 template <typename T> 91 void setProperty(const std::string& interface, const std::string& propertyName, 92 const std::string& path, const std::string& service, 93 sdbusplus::bus_t& bus, T& value) 94 { 95 std::variant<T> propertyValue(value); 96 97 auto method = bus.new_method_call(service.c_str(), path.c_str(), 98 PROPERTY_INTF, "Set"); 99 100 method.append(interface, propertyName, propertyValue); 101 102 auto reply = bus.call(method); 103 } 104 105 /** 106 * @brief Get all D-Bus properties 107 * 108 * @param[in] bus - the D-Bus object 109 * @param[in] path - the D-Bus object path 110 * @param[in] interface - the D-Bus interface name 111 * @param[in] service - the D-Bus service name (optional) 112 * 113 * @return DbusPropertyMap - Map of property names and values 114 */ 115 DbusPropertyMap getAllProperties(sdbusplus::bus_t& bus, const std::string& path, 116 const std::string& interface, 117 const std::string& service = std::string()); 118 119 /** @brief Get subtree from the object mapper. 120 * 121 * Helper function to find objects, services, and interfaces. 122 * See: 123 * https://github.com/openbmc/docs/blob/master/architecture/object-mapper.md 124 * 125 * @param[in] bus - The D-Bus object. 126 * @param[in] path - The root of the tree to search. 127 * @param[in] interface - Interface in the subtree to search for 128 * @param[in] depth - The number of path elements to descend. 129 * 130 * @return DbusSubtree - Map of object paths to a map of service names to their 131 * interfaces. 132 */ 133 DbusSubtree getSubTree(sdbusplus::bus_t& bus, const std::string& path, 134 const std::string& interface, int32_t depth); 135 136 /** @brief Get subtree from the object mapper. 137 * 138 * Helper function to find objects, services, and interfaces. 139 * See: 140 * https://github.com/openbmc/docs/blob/master/architecture/object-mapper.md 141 * 142 * @param[in] bus - The D-Bus object. 143 * @param[in] path - The root of the tree to search. 144 * @param[in] interfaces - Interfaces in the subtree to search for. 145 * @param[in] depth - The number of path elements to descend. 146 * 147 * @return DbusSubtree - Map of object paths to a map of service names to their 148 * interfaces. 149 */ 150 DbusSubtree getSubTree(sdbusplus::bus_t& bus, const std::string& path, 151 const std::vector<std::string>& interfaces, 152 int32_t depth); 153 154 /** @brief GetAssociatedSubTreePaths wrapper from the object mapper. 155 * 156 * Helper function to find object paths that implement a certain 157 * interface and are also an association endpoint. 158 * See: 159 * https://github.com/openbmc/docs/blob/master/architecture/object-mapper.md 160 * 161 * @param[in] bus - The D-Bus object. 162 * @param[in] associationPath - The association it must be an endpoint of. 163 * @param[in] path - The root of the tree to search. 164 * @param[in] interfaces - The interfaces in the subtree to search for 165 * @param[in] depth - The number of path elements to descend. 166 * 167 * @return std::vector<DbusPath> - The object paths. 168 */ 169 std::vector<DbusPath> getAssociatedSubTreePaths( 170 sdbusplus::bus_t& bus, 171 const sdbusplus::message::object_path& associationPath, 172 const sdbusplus::message::object_path& path, 173 const std::vector<std::string>& interfaces, int32_t depth); 174 175 /** 176 * Logs an error and powers off the system. 177 * 178 * @tparam T - error that will be logged before the power off 179 * @param[in] bus - D-Bus object 180 */ 181 template <typename T> 182 void powerOff(sdbusplus::bus_t& bus) 183 { 184 phosphor::logging::report<T>(); 185 186 auto method = bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_ROOT, 187 SYSTEMD_INTERFACE, "StartUnit"); 188 189 method.append(POWEROFF_TARGET); 190 method.append("replace"); 191 192 bus.call_noreply(method); 193 } 194 195 /** 196 * Load json from a file 197 * 198 * @param[in] path - The path of the json file 199 * 200 * @return The nlohmann::json object 201 */ 202 nlohmann::json loadJSONFromFile(const char* path); 203 204 /** 205 * Get PmBus access type from the json config 206 * 207 * @param[in] json - The json object 208 * 209 * @return The pmbus access type 210 */ 211 phosphor::pmbus::Type getPMBusAccessType(const nlohmann::json& json); 212 213 /** 214 * Check if power is on 215 * 216 * @param[in] bus - D-Bus object 217 * @param[in] defaultState - The default state if the function fails to get 218 * the power state. 219 * 220 * @return true if power is on, otherwise false; 221 * defaultState if it fails to get the power state. 222 */ 223 bool isPoweredOn(sdbusplus::bus_t& bus, bool defaultState = false); 224 225 /** 226 * Get all PSU inventory paths from D-Bus 227 * 228 * @param[in] bus - D-Bus object 229 * 230 * @return The list of PSU inventory paths 231 */ 232 std::vector<std::string> getPSUInventoryPaths(sdbusplus::bus_t& bus); 233 234 /** 235 * @detail Get all chassis inventory paths from D-Bus 236 * 237 * @param[in] bus - D-Bus object 238 * 239 * @return The list of chassis inventory paths 240 */ 241 std::vector<std::string> getChassisInventoryPaths(sdbusplus::bus_t& bus); 242 243 /** 244 * @brief Retrieve the chassis ID for the given D-Bus inventory path. 245 * Query the D-Bus interface for inventory object path and retrieve its unique 246 * ID (ID specified by SlotNumber) 247 * 248 * @param[in] bus - D-Bus object 249 * @param[in] path - The inventory manager D-Bus path for a chassis. 250 * 251 * @return uint64_t - Chassis unique ID 252 */ 253 uint64_t getChassisInventoryUniqueId(sdbusplus::bus_t& bus, 254 const std::string& path); 255 /** 256 * @brief Retrieve the parent chassis unique ID from the Entity Manager. 257 * Given a D-Bus object path, this function extracts the parent path (board or 258 * chassis) and retrieve the chassis unique ID from Entity Manager. 259 * 260 * @param[in] bus - D-Bus object 261 * @param[in] path - The EntityManager D-Bus path for hardware within a chassis 262 * or board. 263 * 264 * @return uint64_t - Chassis unique ID 265 * 266 * @note This function assumes the parent object path contains property in 267 * Entity Manager. 268 */ 269 uint64_t getParentEMUniqueId(sdbusplus::bus_t& bus, const std::string& path); 270 271 } // namespace util 272 } // namespace power 273 } // namespace phosphor 274