1 #pragma once 2 3 #include "pmbus.hpp" 4 5 #include <nlohmann/json.hpp> 6 #include <phosphor-logging/elog.hpp> 7 #include <phosphor-logging/log.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 26 using DbusPath = std::string; 27 using DbusProperty = std::string; 28 using DbusService = std::string; 29 using DbusInterface = std::string; 30 using DbusInterfaceList = std::vector<DbusInterface>; 31 using DbusSubtree = 32 std::map<DbusPath, std::map<DbusService, DbusInterfaceList>>; 33 using DbusVariant = 34 std::variant<bool, uint64_t, std::string, std::vector<uint64_t>>; 35 using DbusPropertyMap = std::map<DbusProperty, DbusVariant>; 36 /** 37 * @brief Get the service name from the mapper for the 38 * interface and path passed in. 39 * 40 * @param[in] path - the D-Bus path name 41 * @param[in] interface - the D-Bus interface name 42 * @param[in] bus - the D-Bus object 43 * @param[in] logError - log error when no service found 44 * 45 * @return The service name 46 */ 47 std::string getService(const std::string& path, const std::string& interface, 48 sdbusplus::bus_t& bus, bool logError = true); 49 50 /** 51 * @brief Read a D-Bus property 52 * 53 * @param[in] interface - the interface the property is on 54 * @param[in] propertName - the name of the property 55 * @param[in] path - the D-Bus path 56 * @param[in] service - the D-Bus service 57 * @param[in] bus - the D-Bus object 58 * @param[out] value - filled in with the property value 59 */ 60 template <typename T> 61 void getProperty(const std::string& interface, const std::string& propertyName, 62 const std::string& path, const std::string& service, 63 sdbusplus::bus_t& bus, T& value) 64 { 65 std::variant<T> property; 66 67 auto method = bus.new_method_call(service.c_str(), path.c_str(), 68 PROPERTY_INTF, "Get"); 69 70 method.append(interface, propertyName); 71 72 auto reply = bus.call(method); 73 74 reply.read(property); 75 value = std::get<T>(property); 76 } 77 78 /** 79 * @brief Write a D-Bus property 80 * 81 * @param[in] interface - the interface the property is on 82 * @param[in] propertName - the name of the property 83 * @param[in] path - the D-Bus path 84 * @param[in] service - the D-Bus service 85 * @param[in] bus - the D-Bus object 86 * @param[in] value - the value to set the property to 87 */ 88 template <typename T> 89 void setProperty(const std::string& interface, const std::string& propertyName, 90 const std::string& path, const std::string& service, 91 sdbusplus::bus_t& bus, T& value) 92 { 93 std::variant<T> propertyValue(value); 94 95 auto method = bus.new_method_call(service.c_str(), path.c_str(), 96 PROPERTY_INTF, "Set"); 97 98 method.append(interface, propertyName, propertyValue); 99 100 auto reply = bus.call(method); 101 } 102 103 /** 104 * @brief Get all D-Bus properties 105 * 106 * @param[in] bus - the D-Bus object 107 * @param[in] path - the D-Bus object path 108 * @param[in] interface - the D-Bus interface name 109 * @param[in] service - the D-Bus service name (optional) 110 * 111 * @return DbusPropertyMap - Map of property names and values 112 */ 113 DbusPropertyMap getAllProperties(sdbusplus::bus_t& bus, const std::string& path, 114 const std::string& interface, 115 const std::string& service = std::string()); 116 117 /** @brief Get subtree from the object mapper. 118 * 119 * Helper function to find objects, services, and interfaces. 120 * See: 121 * https://github.com/openbmc/docs/blob/master/architecture/object-mapper.md 122 * 123 * @param[in] bus - The D-Bus object. 124 * @param[in] path - The root of the tree to search. 125 * @param[in] interface - Interface in the subtree to search for 126 * @param[in] depth - The number of path elements to descend. 127 * 128 * @return DbusSubtree - Map of object paths to a map of service names to their 129 * interfaces. 130 */ 131 DbusSubtree getSubTree(sdbusplus::bus_t& bus, const std::string& path, 132 const std::string& interface, int32_t depth); 133 134 /** @brief Get subtree from the object mapper. 135 * 136 * Helper function to find objects, services, and interfaces. 137 * See: 138 * https://github.com/openbmc/docs/blob/master/architecture/object-mapper.md 139 * 140 * @param[in] bus - The D-Bus object. 141 * @param[in] path - The root of the tree to search. 142 * @param[in] interfaces - Interfaces in the subtree to search for. 143 * @param[in] depth - The number of path elements to descend. 144 * 145 * @return DbusSubtree - Map of object paths to a map of service names to their 146 * interfaces. 147 */ 148 DbusSubtree getSubTree(sdbusplus::bus_t& bus, const std::string& path, 149 const std::vector<std::string>& interfaces, 150 int32_t depth); 151 152 /** @brief GetAssociatedSubTreePaths wrapper from the object mapper. 153 * 154 * Helper function to find object paths that implement a certain 155 * interface and are also an association endpoint. 156 * See: 157 * https://github.com/openbmc/docs/blob/master/architecture/object-mapper.md 158 * 159 * @param[in] bus - The D-Bus object. 160 * @param[in] associationPath - The association it must be an endpoint of. 161 * @param[in] path - The root of the tree to search. 162 * @param[in] interfaces - The interfaces in the subtree to search for 163 * @param[in] depth - The number of path elements to descend. 164 * 165 * @return std::vector<DbusPath> - The object paths. 166 */ 167 std::vector<DbusPath> getAssociatedSubTreePaths( 168 sdbusplus::bus_t& bus, 169 const sdbusplus::message::object_path& associationPath, 170 const sdbusplus::message::object_path& path, 171 const std::vector<std::string>& interfaces, int32_t depth); 172 173 /** 174 * Logs an error and powers off the system. 175 * 176 * @tparam T - error that will be logged before the power off 177 * @param[in] bus - D-Bus object 178 */ 179 template <typename T> 180 void powerOff(sdbusplus::bus_t& bus) 181 { 182 phosphor::logging::report<T>(); 183 184 auto method = bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_ROOT, 185 SYSTEMD_INTERFACE, "StartUnit"); 186 187 method.append(POWEROFF_TARGET); 188 method.append("replace"); 189 190 bus.call_noreply(method); 191 } 192 193 /** 194 * Load json from a file 195 * 196 * @param[in] path - The path of the json file 197 * 198 * @return The nlohmann::json object 199 */ 200 nlohmann::json loadJSONFromFile(const char* path); 201 202 /** 203 * Get PmBus access type from the json config 204 * 205 * @param[in] json - The json object 206 * 207 * @return The pmbus access type 208 */ 209 phosphor::pmbus::Type getPMBusAccessType(const nlohmann::json& json); 210 211 /** 212 * Check if power is on 213 * 214 * @param[in] bus - D-Bus object 215 * @param[in] defaultState - The default state if the function fails to get 216 * the power state. 217 * 218 * @return true if power is on, otherwise false; 219 * defaultState if it fails to get the power state. 220 */ 221 bool isPoweredOn(sdbusplus::bus_t& bus, bool defaultState = false); 222 223 /** 224 * Get all PSU inventory paths from D-Bus 225 * 226 * @param[in] bus - D-Bus object 227 * 228 * @return The list of PSU inventory paths 229 */ 230 std::vector<std::string> getPSUInventoryPaths(sdbusplus::bus_t& bus); 231 232 } // namespace util 233 } // namespace power 234 } // namespace phosphor 235