1974c916eSMatt Spinler #pragma once 2974c916eSMatt Spinler 34070546eSLei YU #include "pmbus.hpp" 44070546eSLei YU 57dc31bb1SLei YU #include <nlohmann/json.hpp> 6882ce956SMatt Spinler #include <phosphor-logging/elog.hpp> 7f0f02b9aSMatt Spinler #include <phosphor-logging/log.hpp> 8974c916eSMatt Spinler #include <sdbusplus/bus.hpp> 9d1bc4cecSBrandon Wyman 10974c916eSMatt Spinler #include <string> 11974c916eSMatt Spinler 12ab093328SLei YU namespace phosphor 13974c916eSMatt Spinler { 14974c916eSMatt Spinler namespace power 15974c916eSMatt Spinler { 16974c916eSMatt Spinler namespace util 17974c916eSMatt Spinler { 18974c916eSMatt Spinler 19882ce956SMatt Spinler constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1"; 20882ce956SMatt Spinler constexpr auto SYSTEMD_ROOT = "/org/freedesktop/systemd1"; 21882ce956SMatt Spinler constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager"; 22882ce956SMatt Spinler constexpr auto POWEROFF_TARGET = "obmc-chassis-hard-poweroff@0.target"; 23974c916eSMatt Spinler constexpr auto PROPERTY_INTF = "org.freedesktop.DBus.Properties"; 24974c916eSMatt Spinler 25c761b5fcSBrandon Wyman using DbusPath = std::string; 264e8b335eSAdriana Kobylak using DbusProperty = std::string; 27c761b5fcSBrandon Wyman using DbusService = std::string; 28c761b5fcSBrandon Wyman using DbusInterface = std::string; 29c761b5fcSBrandon Wyman using DbusInterfaceList = std::vector<DbusInterface>; 30c761b5fcSBrandon Wyman using DbusSubtree = 31c761b5fcSBrandon Wyman std::map<DbusPath, std::map<DbusService, DbusInterfaceList>>; 32*886574cdSAdriana Kobylak using DbusVariant = 33*886574cdSAdriana Kobylak std::variant<bool, uint64_t, std::string, std::vector<uint64_t>>; 344e8b335eSAdriana Kobylak using DbusPropertyMap = std::map<DbusProperty, DbusVariant>; 35974c916eSMatt Spinler /** 36974c916eSMatt Spinler * @brief Get the service name from the mapper for the 37974c916eSMatt Spinler * interface and path passed in. 38974c916eSMatt Spinler * 39974c916eSMatt Spinler * @param[in] path - the D-Bus path name 40974c916eSMatt Spinler * @param[in] interface - the D-Bus interface name 41974c916eSMatt Spinler * @param[in] bus - the D-Bus object 42d262440dSMatthew Barth * @param[in] logError - log error when no service found 43974c916eSMatt Spinler * 44974c916eSMatt Spinler * @return The service name 45974c916eSMatt Spinler */ 46f0f02b9aSMatt Spinler std::string getService(const std::string& path, const std::string& interface, 47d262440dSMatthew Barth sdbusplus::bus::bus& bus, bool logError = true); 48974c916eSMatt Spinler 49974c916eSMatt Spinler /** 50974c916eSMatt Spinler * @brief Read a D-Bus property 51974c916eSMatt Spinler * 52974c916eSMatt Spinler * @param[in] interface - the interface the property is on 53974c916eSMatt Spinler * @param[in] propertName - the name of the property 54974c916eSMatt Spinler * @param[in] path - the D-Bus path 55974c916eSMatt Spinler * @param[in] service - the D-Bus service 56974c916eSMatt Spinler * @param[in] bus - the D-Bus object 57974c916eSMatt Spinler * @param[out] value - filled in with the property value 58974c916eSMatt Spinler */ 59974c916eSMatt Spinler template <typename T> 60f0f02b9aSMatt Spinler void getProperty(const std::string& interface, const std::string& propertyName, 61f0f02b9aSMatt Spinler const std::string& path, const std::string& service, 62f0f02b9aSMatt Spinler sdbusplus::bus::bus& bus, T& value) 63974c916eSMatt Spinler { 64abe49418SPatrick Williams std::variant<T> property; 65974c916eSMatt Spinler 66f0f02b9aSMatt Spinler auto method = bus.new_method_call(service.c_str(), path.c_str(), 67f0f02b9aSMatt Spinler PROPERTY_INTF, "Get"); 68974c916eSMatt Spinler 69974c916eSMatt Spinler method.append(interface, propertyName); 70974c916eSMatt Spinler 71974c916eSMatt Spinler auto reply = bus.call(method); 72974c916eSMatt Spinler 73974c916eSMatt Spinler reply.read(property); 74365d61c6SPatrick Williams value = std::get<T>(property); 75974c916eSMatt Spinler } 76974c916eSMatt Spinler 7748b4a430SMatt Spinler /** 780a4f519bSBrandon Wyman * @brief Write a D-Bus property 790a4f519bSBrandon Wyman * 800a4f519bSBrandon Wyman * @param[in] interface - the interface the property is on 810a4f519bSBrandon Wyman * @param[in] propertName - the name of the property 820a4f519bSBrandon Wyman * @param[in] path - the D-Bus path 830a4f519bSBrandon Wyman * @param[in] service - the D-Bus service 840a4f519bSBrandon Wyman * @param[in] bus - the D-Bus object 850a4f519bSBrandon Wyman * @param[in] value - the value to set the property to 860a4f519bSBrandon Wyman */ 870a4f519bSBrandon Wyman template <typename T> 88f0f02b9aSMatt Spinler void setProperty(const std::string& interface, const std::string& propertyName, 89f0f02b9aSMatt Spinler const std::string& path, const std::string& service, 90f0f02b9aSMatt Spinler sdbusplus::bus::bus& bus, T& value) 910a4f519bSBrandon Wyman { 92abe49418SPatrick Williams std::variant<T> propertyValue(value); 930a4f519bSBrandon Wyman 94f0f02b9aSMatt Spinler auto method = bus.new_method_call(service.c_str(), path.c_str(), 95f0f02b9aSMatt Spinler PROPERTY_INTF, "Set"); 960a4f519bSBrandon Wyman 970a4f519bSBrandon Wyman method.append(interface, propertyName, propertyValue); 980a4f519bSBrandon Wyman 990a4f519bSBrandon Wyman auto reply = bus.call(method); 1000a4f519bSBrandon Wyman } 1010a4f519bSBrandon Wyman 1024e8b335eSAdriana Kobylak /** 1034e8b335eSAdriana Kobylak * @brief Get all D-Bus properties 1044e8b335eSAdriana Kobylak * 1054e8b335eSAdriana Kobylak * @param[in] bus - the D-Bus object 1064e8b335eSAdriana Kobylak * @param[in] path - the D-Bus object path 1074e8b335eSAdriana Kobylak * @param[in] interface - the D-Bus interface name 1084e8b335eSAdriana Kobylak * @param[in] service - the D-Bus service name (optional) 1094e8b335eSAdriana Kobylak * 1104e8b335eSAdriana Kobylak * @return DbusPropertyMap - Map of property names and values 1114e8b335eSAdriana Kobylak */ 1124e8b335eSAdriana Kobylak DbusPropertyMap getAllProperties(sdbusplus::bus::bus& bus, 1134e8b335eSAdriana Kobylak const std::string& path, 1144e8b335eSAdriana Kobylak const std::string& interface, 1154e8b335eSAdriana Kobylak const std::string& service = std::string()); 1164e8b335eSAdriana Kobylak 117c761b5fcSBrandon Wyman /** @brief Get subtree from the object mapper. 118c761b5fcSBrandon Wyman * 119c761b5fcSBrandon Wyman * Helper function to find objects, services, and interfaces. 120c761b5fcSBrandon Wyman * See: 121c761b5fcSBrandon Wyman * https://github.com/openbmc/docs/blob/master/architecture/object-mapper.md 122c761b5fcSBrandon Wyman * 123c761b5fcSBrandon Wyman * @param[in] bus - The D-Bus object. 124c761b5fcSBrandon Wyman * @param[in] path - The root of the tree to search. 125c761b5fcSBrandon Wyman * @param[in] interface - Interface in the subtree to search for 126c761b5fcSBrandon Wyman * @param[in] depth - The number of path elements to descend. 127c761b5fcSBrandon Wyman * 128c761b5fcSBrandon Wyman * @return DbusSubtree - Map of object paths to a map of service names to their 129c761b5fcSBrandon Wyman * interfaces. 130c761b5fcSBrandon Wyman */ 131c761b5fcSBrandon Wyman DbusSubtree getSubTree(sdbusplus::bus::bus& bus, const std::string& path, 132c761b5fcSBrandon Wyman const std::string& interface, int32_t depth); 133c761b5fcSBrandon Wyman 1340a4f519bSBrandon Wyman /** 135882ce956SMatt Spinler * Logs an error and powers off the system. 13648b4a430SMatt Spinler * 137882ce956SMatt Spinler * @tparam T - error that will be logged before the power off 13848b4a430SMatt Spinler * @param[in] bus - D-Bus object 13948b4a430SMatt Spinler */ 140882ce956SMatt Spinler template <typename T> 141882ce956SMatt Spinler void powerOff(sdbusplus::bus::bus& bus) 142882ce956SMatt Spinler { 143882ce956SMatt Spinler phosphor::logging::report<T>(); 144882ce956SMatt Spinler 145f0f02b9aSMatt Spinler auto method = bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_ROOT, 146f0f02b9aSMatt Spinler SYSTEMD_INTERFACE, "StartUnit"); 147882ce956SMatt Spinler 148882ce956SMatt Spinler method.append(POWEROFF_TARGET); 149882ce956SMatt Spinler method.append("replace"); 150882ce956SMatt Spinler 151882ce956SMatt Spinler bus.call_noreply(method); 152882ce956SMatt Spinler } 15348b4a430SMatt Spinler 1547dc31bb1SLei YU /** 1557dc31bb1SLei YU * Load json from a file 1567dc31bb1SLei YU * 1577dc31bb1SLei YU * @param[in] path - The path of the json file 1587dc31bb1SLei YU * 1597dc31bb1SLei YU * @return The nlohmann::json object 1607dc31bb1SLei YU */ 1617dc31bb1SLei YU nlohmann::json loadJSONFromFile(const char* path); 1627dc31bb1SLei YU 1634070546eSLei YU /** 1644070546eSLei YU * Get PmBus access type from the json config 1654070546eSLei YU * 1664070546eSLei YU * @param[in] json - The json object 1674070546eSLei YU * 1684070546eSLei YU * @return The pmbus access type 1694070546eSLei YU */ 1704070546eSLei YU phosphor::pmbus::Type getPMBusAccessType(const nlohmann::json& json); 1714070546eSLei YU 172cfc040c7SLei YU /** 173cfc040c7SLei YU * Check if power is on 174cfc040c7SLei YU * 175e8c9cd64SLei YU * @param[in] bus - D-Bus object 176e8c9cd64SLei YU * @param[in] defaultState - The default state if the function fails to get 177e8c9cd64SLei YU * the power state. 178e8c9cd64SLei YU * 179e8c9cd64SLei YU * @return true if power is on, otherwise false; 180e8c9cd64SLei YU * defaultState if it fails to get the power state. 181cfc040c7SLei YU */ 182e8c9cd64SLei YU bool isPoweredOn(sdbusplus::bus::bus& bus, bool defaultState = false); 183e8c9cd64SLei YU 184e8c9cd64SLei YU /** 185e8c9cd64SLei YU * Get all PSU inventory paths from D-Bus 186e8c9cd64SLei YU * 187e8c9cd64SLei YU * @param[in] bus - D-Bus object 188e8c9cd64SLei YU * 189e8c9cd64SLei YU * @return The list of PSU inventory paths 190e8c9cd64SLei YU */ 191e8c9cd64SLei YU std::vector<std::string> getPSUInventoryPaths(sdbusplus::bus::bus& bus); 192cfc040c7SLei YU 193f0f02b9aSMatt Spinler } // namespace util 194f0f02b9aSMatt Spinler } // namespace power 195ab093328SLei YU } // namespace phosphor 196