xref: /openbmc/phosphor-power/utility.hpp (revision 886574cd772be492212cd5a1fde8bc2de8dabf9b)
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