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