xref: /openbmc/phosphor-power/utility.hpp (revision 365d61c68825435d2afeb0c2e1ec007ccec5b603)
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 
25974c916eSMatt Spinler /**
26974c916eSMatt Spinler  * @brief Get the service name from the mapper for the
27974c916eSMatt Spinler  *        interface and path passed in.
28974c916eSMatt Spinler  *
29974c916eSMatt Spinler  * @param[in] path - the D-Bus path name
30974c916eSMatt Spinler  * @param[in] interface - the D-Bus interface name
31974c916eSMatt Spinler  * @param[in] bus - the D-Bus object
32d262440dSMatthew Barth  * @param[in] logError - log error when no service found
33974c916eSMatt Spinler  *
34974c916eSMatt Spinler  * @return The service name
35974c916eSMatt Spinler  */
36f0f02b9aSMatt Spinler std::string getService(const std::string& path, const std::string& interface,
37d262440dSMatthew Barth                        sdbusplus::bus::bus& bus, bool logError = true);
38974c916eSMatt Spinler 
39974c916eSMatt Spinler /**
40974c916eSMatt Spinler  * @brief Read a D-Bus property
41974c916eSMatt Spinler  *
42974c916eSMatt Spinler  * @param[in] interface - the interface the property is on
43974c916eSMatt Spinler  * @param[in] propertName - the name of the property
44974c916eSMatt Spinler  * @param[in] path - the D-Bus path
45974c916eSMatt Spinler  * @param[in] service - the D-Bus service
46974c916eSMatt Spinler  * @param[in] bus - the D-Bus object
47974c916eSMatt Spinler  * @param[out] value - filled in with the property value
48974c916eSMatt Spinler  */
49974c916eSMatt Spinler template <typename T>
50f0f02b9aSMatt Spinler void getProperty(const std::string& interface, const std::string& propertyName,
51f0f02b9aSMatt Spinler                  const std::string& path, const std::string& service,
52f0f02b9aSMatt Spinler                  sdbusplus::bus::bus& bus, T& value)
53974c916eSMatt Spinler {
54974c916eSMatt Spinler     sdbusplus::message::variant<T> property;
55974c916eSMatt Spinler 
56f0f02b9aSMatt Spinler     auto method = bus.new_method_call(service.c_str(), path.c_str(),
57f0f02b9aSMatt Spinler                                       PROPERTY_INTF, "Get");
58974c916eSMatt Spinler 
59974c916eSMatt Spinler     method.append(interface, propertyName);
60974c916eSMatt Spinler 
61974c916eSMatt Spinler     auto reply = bus.call(method);
62974c916eSMatt Spinler 
63974c916eSMatt Spinler     reply.read(property);
64*365d61c6SPatrick Williams     value = std::get<T>(property);
65974c916eSMatt Spinler }
66974c916eSMatt Spinler 
6748b4a430SMatt Spinler /**
680a4f519bSBrandon Wyman  * @brief Write a D-Bus property
690a4f519bSBrandon Wyman  *
700a4f519bSBrandon Wyman  * @param[in] interface - the interface the property is on
710a4f519bSBrandon Wyman  * @param[in] propertName - the name of the property
720a4f519bSBrandon Wyman  * @param[in] path - the D-Bus path
730a4f519bSBrandon Wyman  * @param[in] service - the D-Bus service
740a4f519bSBrandon Wyman  * @param[in] bus - the D-Bus object
750a4f519bSBrandon Wyman  * @param[in] value - the value to set the property to
760a4f519bSBrandon Wyman  */
770a4f519bSBrandon Wyman template <typename T>
78f0f02b9aSMatt Spinler void setProperty(const std::string& interface, const std::string& propertyName,
79f0f02b9aSMatt Spinler                  const std::string& path, const std::string& service,
80f0f02b9aSMatt Spinler                  sdbusplus::bus::bus& bus, T& value)
810a4f519bSBrandon Wyman {
820a4f519bSBrandon Wyman     sdbusplus::message::variant<T> propertyValue(value);
830a4f519bSBrandon Wyman 
84f0f02b9aSMatt Spinler     auto method = bus.new_method_call(service.c_str(), path.c_str(),
85f0f02b9aSMatt Spinler                                       PROPERTY_INTF, "Set");
860a4f519bSBrandon Wyman 
870a4f519bSBrandon Wyman     method.append(interface, propertyName, propertyValue);
880a4f519bSBrandon Wyman 
890a4f519bSBrandon Wyman     auto reply = bus.call(method);
900a4f519bSBrandon Wyman }
910a4f519bSBrandon Wyman 
920a4f519bSBrandon Wyman /**
93882ce956SMatt Spinler  * Logs an error and powers off the system.
9448b4a430SMatt Spinler  *
95882ce956SMatt Spinler  * @tparam T - error that will be logged before the power off
9648b4a430SMatt Spinler  * @param[in] bus - D-Bus object
9748b4a430SMatt Spinler  */
98882ce956SMatt Spinler template <typename T>
99882ce956SMatt Spinler void powerOff(sdbusplus::bus::bus& bus)
100882ce956SMatt Spinler {
101882ce956SMatt Spinler     phosphor::logging::report<T>();
102882ce956SMatt Spinler 
103f0f02b9aSMatt Spinler     auto method = bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_ROOT,
104f0f02b9aSMatt Spinler                                       SYSTEMD_INTERFACE, "StartUnit");
105882ce956SMatt Spinler 
106882ce956SMatt Spinler     method.append(POWEROFF_TARGET);
107882ce956SMatt Spinler     method.append("replace");
108882ce956SMatt Spinler 
109882ce956SMatt Spinler     bus.call_noreply(method);
110882ce956SMatt Spinler }
11148b4a430SMatt Spinler 
1127dc31bb1SLei YU /**
1137dc31bb1SLei YU  * Load json from a file
1147dc31bb1SLei YU  *
1157dc31bb1SLei YU  * @param[in] path - The path of the json file
1167dc31bb1SLei YU  *
1177dc31bb1SLei YU  * @return The nlohmann::json object
1187dc31bb1SLei YU  */
1197dc31bb1SLei YU nlohmann::json loadJSONFromFile(const char* path);
1207dc31bb1SLei YU 
1214070546eSLei YU /**
1224070546eSLei YU  * Get PmBus access type from the json config
1234070546eSLei YU  *
1244070546eSLei YU  * @param[in] json - The json object
1254070546eSLei YU  *
1264070546eSLei YU  * @return The pmbus access type
1274070546eSLei YU  */
1284070546eSLei YU phosphor::pmbus::Type getPMBusAccessType(const nlohmann::json& json);
1294070546eSLei YU 
130cfc040c7SLei YU /**
131cfc040c7SLei YU  * Check if power is on
132cfc040c7SLei YU  *
133e8c9cd64SLei YU  * @param[in] bus - D-Bus object
134e8c9cd64SLei YU  * @param[in] defaultState - The default state if the function fails to get
135e8c9cd64SLei YU  *                           the power state.
136e8c9cd64SLei YU  *
137e8c9cd64SLei YU  * @return true if power is on, otherwise false;
138e8c9cd64SLei YU  *         defaultState if it fails to get the power state.
139cfc040c7SLei YU  */
140e8c9cd64SLei YU bool isPoweredOn(sdbusplus::bus::bus& bus, bool defaultState = false);
141e8c9cd64SLei YU 
142e8c9cd64SLei YU /**
143e8c9cd64SLei YU  * Get all PSU inventory paths from D-Bus
144e8c9cd64SLei YU  *
145e8c9cd64SLei YU  * @param[in] bus - D-Bus object
146e8c9cd64SLei YU  *
147e8c9cd64SLei YU  * @return The list of PSU inventory paths
148e8c9cd64SLei YU  */
149e8c9cd64SLei YU std::vector<std::string> getPSUInventoryPaths(sdbusplus::bus::bus& bus);
150cfc040c7SLei YU 
151f0f02b9aSMatt Spinler } // namespace util
152f0f02b9aSMatt Spinler } // namespace power
153ab093328SLei YU } // namespace phosphor
154