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