xref: /openbmc/phosphor-power/utility.hpp (revision c761b5fc9d7ceeb69ab77edb7441b5a6209dcbc5)
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 
25*c761b5fcSBrandon Wyman using DbusPath = std::string;
26*c761b5fcSBrandon Wyman using DbusService = std::string;
27*c761b5fcSBrandon Wyman using DbusInterface = std::string;
28*c761b5fcSBrandon Wyman using DbusInterfaceList = std::vector<DbusInterface>;
29*c761b5fcSBrandon Wyman using DbusSubtree =
30*c761b5fcSBrandon Wyman     std::map<DbusPath, std::map<DbusService, DbusInterfaceList>>;
31974c916eSMatt Spinler /**
32974c916eSMatt Spinler  * @brief Get the service name from the mapper for the
33974c916eSMatt Spinler  *        interface and path passed in.
34974c916eSMatt Spinler  *
35974c916eSMatt Spinler  * @param[in] path - the D-Bus path name
36974c916eSMatt Spinler  * @param[in] interface - the D-Bus interface name
37974c916eSMatt Spinler  * @param[in] bus - the D-Bus object
38d262440dSMatthew Barth  * @param[in] logError - log error when no service found
39974c916eSMatt Spinler  *
40974c916eSMatt Spinler  * @return The service name
41974c916eSMatt Spinler  */
42f0f02b9aSMatt Spinler std::string getService(const std::string& path, const std::string& interface,
43d262440dSMatthew Barth                        sdbusplus::bus::bus& bus, bool logError = true);
44974c916eSMatt Spinler 
45974c916eSMatt Spinler /**
46974c916eSMatt Spinler  * @brief Read a D-Bus property
47974c916eSMatt Spinler  *
48974c916eSMatt Spinler  * @param[in] interface - the interface the property is on
49974c916eSMatt Spinler  * @param[in] propertName - the name of the property
50974c916eSMatt Spinler  * @param[in] path - the D-Bus path
51974c916eSMatt Spinler  * @param[in] service - the D-Bus service
52974c916eSMatt Spinler  * @param[in] bus - the D-Bus object
53974c916eSMatt Spinler  * @param[out] value - filled in with the property value
54974c916eSMatt Spinler  */
55974c916eSMatt Spinler template <typename T>
56f0f02b9aSMatt Spinler void getProperty(const std::string& interface, const std::string& propertyName,
57f0f02b9aSMatt Spinler                  const std::string& path, const std::string& service,
58f0f02b9aSMatt Spinler                  sdbusplus::bus::bus& bus, T& value)
59974c916eSMatt Spinler {
60abe49418SPatrick Williams     std::variant<T> property;
61974c916eSMatt Spinler 
62f0f02b9aSMatt Spinler     auto method = bus.new_method_call(service.c_str(), path.c_str(),
63f0f02b9aSMatt Spinler                                       PROPERTY_INTF, "Get");
64974c916eSMatt Spinler 
65974c916eSMatt Spinler     method.append(interface, propertyName);
66974c916eSMatt Spinler 
67974c916eSMatt Spinler     auto reply = bus.call(method);
68974c916eSMatt Spinler 
69974c916eSMatt Spinler     reply.read(property);
70365d61c6SPatrick Williams     value = std::get<T>(property);
71974c916eSMatt Spinler }
72974c916eSMatt Spinler 
7348b4a430SMatt Spinler /**
740a4f519bSBrandon Wyman  * @brief Write a D-Bus property
750a4f519bSBrandon Wyman  *
760a4f519bSBrandon Wyman  * @param[in] interface - the interface the property is on
770a4f519bSBrandon Wyman  * @param[in] propertName - the name of the property
780a4f519bSBrandon Wyman  * @param[in] path - the D-Bus path
790a4f519bSBrandon Wyman  * @param[in] service - the D-Bus service
800a4f519bSBrandon Wyman  * @param[in] bus - the D-Bus object
810a4f519bSBrandon Wyman  * @param[in] value - the value to set the property to
820a4f519bSBrandon Wyman  */
830a4f519bSBrandon Wyman template <typename T>
84f0f02b9aSMatt Spinler void setProperty(const std::string& interface, const std::string& propertyName,
85f0f02b9aSMatt Spinler                  const std::string& path, const std::string& service,
86f0f02b9aSMatt Spinler                  sdbusplus::bus::bus& bus, T& value)
870a4f519bSBrandon Wyman {
88abe49418SPatrick Williams     std::variant<T> propertyValue(value);
890a4f519bSBrandon Wyman 
90f0f02b9aSMatt Spinler     auto method = bus.new_method_call(service.c_str(), path.c_str(),
91f0f02b9aSMatt Spinler                                       PROPERTY_INTF, "Set");
920a4f519bSBrandon Wyman 
930a4f519bSBrandon Wyman     method.append(interface, propertyName, propertyValue);
940a4f519bSBrandon Wyman 
950a4f519bSBrandon Wyman     auto reply = bus.call(method);
960a4f519bSBrandon Wyman }
970a4f519bSBrandon Wyman 
98*c761b5fcSBrandon Wyman /** @brief Get subtree from the object mapper.
99*c761b5fcSBrandon Wyman  *
100*c761b5fcSBrandon Wyman  * Helper function to find objects, services, and interfaces.
101*c761b5fcSBrandon Wyman  * See:
102*c761b5fcSBrandon Wyman  * https://github.com/openbmc/docs/blob/master/architecture/object-mapper.md
103*c761b5fcSBrandon Wyman  *
104*c761b5fcSBrandon Wyman  * @param[in] bus - The D-Bus object.
105*c761b5fcSBrandon Wyman  * @param[in] path - The root of the tree to search.
106*c761b5fcSBrandon Wyman  * @param[in] interface - Interface in the subtree to search for
107*c761b5fcSBrandon Wyman  * @param[in] depth - The number of path elements to descend.
108*c761b5fcSBrandon Wyman  *
109*c761b5fcSBrandon Wyman  * @return DbusSubtree - Map of object paths to a map of service names to their
110*c761b5fcSBrandon Wyman  *                       interfaces.
111*c761b5fcSBrandon Wyman  */
112*c761b5fcSBrandon Wyman DbusSubtree getSubTree(sdbusplus::bus::bus& bus, const std::string& path,
113*c761b5fcSBrandon Wyman                        const std::string& interface, int32_t depth);
114*c761b5fcSBrandon Wyman 
1150a4f519bSBrandon Wyman /**
116882ce956SMatt Spinler  * Logs an error and powers off the system.
11748b4a430SMatt Spinler  *
118882ce956SMatt Spinler  * @tparam T - error that will be logged before the power off
11948b4a430SMatt Spinler  * @param[in] bus - D-Bus object
12048b4a430SMatt Spinler  */
121882ce956SMatt Spinler template <typename T>
122882ce956SMatt Spinler void powerOff(sdbusplus::bus::bus& bus)
123882ce956SMatt Spinler {
124882ce956SMatt Spinler     phosphor::logging::report<T>();
125882ce956SMatt Spinler 
126f0f02b9aSMatt Spinler     auto method = bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_ROOT,
127f0f02b9aSMatt Spinler                                       SYSTEMD_INTERFACE, "StartUnit");
128882ce956SMatt Spinler 
129882ce956SMatt Spinler     method.append(POWEROFF_TARGET);
130882ce956SMatt Spinler     method.append("replace");
131882ce956SMatt Spinler 
132882ce956SMatt Spinler     bus.call_noreply(method);
133882ce956SMatt Spinler }
13448b4a430SMatt Spinler 
1357dc31bb1SLei YU /**
1367dc31bb1SLei YU  * Load json from a file
1377dc31bb1SLei YU  *
1387dc31bb1SLei YU  * @param[in] path - The path of the json file
1397dc31bb1SLei YU  *
1407dc31bb1SLei YU  * @return The nlohmann::json object
1417dc31bb1SLei YU  */
1427dc31bb1SLei YU nlohmann::json loadJSONFromFile(const char* path);
1437dc31bb1SLei YU 
1444070546eSLei YU /**
1454070546eSLei YU  * Get PmBus access type from the json config
1464070546eSLei YU  *
1474070546eSLei YU  * @param[in] json - The json object
1484070546eSLei YU  *
1494070546eSLei YU  * @return The pmbus access type
1504070546eSLei YU  */
1514070546eSLei YU phosphor::pmbus::Type getPMBusAccessType(const nlohmann::json& json);
1524070546eSLei YU 
153cfc040c7SLei YU /**
154cfc040c7SLei YU  * Check if power is on
155cfc040c7SLei YU  *
156e8c9cd64SLei YU  * @param[in] bus - D-Bus object
157e8c9cd64SLei YU  * @param[in] defaultState - The default state if the function fails to get
158e8c9cd64SLei YU  *                           the power state.
159e8c9cd64SLei YU  *
160e8c9cd64SLei YU  * @return true if power is on, otherwise false;
161e8c9cd64SLei YU  *         defaultState if it fails to get the power state.
162cfc040c7SLei YU  */
163e8c9cd64SLei YU bool isPoweredOn(sdbusplus::bus::bus& bus, bool defaultState = false);
164e8c9cd64SLei YU 
165e8c9cd64SLei YU /**
166e8c9cd64SLei YU  * Get all PSU inventory paths from D-Bus
167e8c9cd64SLei YU  *
168e8c9cd64SLei YU  * @param[in] bus - D-Bus object
169e8c9cd64SLei YU  *
170e8c9cd64SLei YU  * @return The list of PSU inventory paths
171e8c9cd64SLei YU  */
172e8c9cd64SLei YU std::vector<std::string> getPSUInventoryPaths(sdbusplus::bus::bus& bus);
173cfc040c7SLei YU 
174f0f02b9aSMatt Spinler } // namespace util
175f0f02b9aSMatt Spinler } // namespace power
176ab093328SLei YU } // namespace phosphor
177