xref: /openbmc/phosphor-power/utility.hpp (revision 3cc348cee87588bfcdf23c8dcee0b456c42a9522)
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>
118270b7d1SShawn McCarney #include <vector>
12974c916eSMatt Spinler 
13ab093328SLei YU namespace phosphor
14974c916eSMatt Spinler {
15974c916eSMatt Spinler namespace power
16974c916eSMatt Spinler {
17974c916eSMatt Spinler namespace util
18974c916eSMatt Spinler {
19974c916eSMatt Spinler 
20882ce956SMatt Spinler constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1";
21882ce956SMatt Spinler constexpr auto SYSTEMD_ROOT = "/org/freedesktop/systemd1";
22882ce956SMatt Spinler constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager";
23882ce956SMatt Spinler constexpr auto POWEROFF_TARGET = "obmc-chassis-hard-poweroff@0.target";
24974c916eSMatt Spinler constexpr auto PROPERTY_INTF = "org.freedesktop.DBus.Properties";
25974c916eSMatt Spinler 
26c761b5fcSBrandon Wyman using DbusPath = std::string;
274e8b335eSAdriana Kobylak using DbusProperty = std::string;
28c761b5fcSBrandon Wyman using DbusService = std::string;
29c761b5fcSBrandon Wyman using DbusInterface = std::string;
30c761b5fcSBrandon Wyman using DbusInterfaceList = std::vector<DbusInterface>;
31c761b5fcSBrandon Wyman using DbusSubtree =
32c761b5fcSBrandon Wyman     std::map<DbusPath, std::map<DbusService, DbusInterfaceList>>;
33886574cdSAdriana Kobylak using DbusVariant =
34*3cc348ceSShawn McCarney     std::variant<bool, uint64_t, std::string, std::vector<uint64_t>,
35*3cc348ceSShawn McCarney                  std::vector<std::string>>;
364e8b335eSAdriana Kobylak using DbusPropertyMap = std::map<DbusProperty, DbusVariant>;
37974c916eSMatt Spinler /**
38974c916eSMatt Spinler  * @brief Get the service name from the mapper for the
39974c916eSMatt Spinler  *        interface and path passed in.
40974c916eSMatt Spinler  *
41974c916eSMatt Spinler  * @param[in] path - the D-Bus path name
42974c916eSMatt Spinler  * @param[in] interface - the D-Bus interface name
43974c916eSMatt Spinler  * @param[in] bus - the D-Bus object
44d262440dSMatthew Barth  * @param[in] logError - log error when no service found
45974c916eSMatt Spinler  *
46974c916eSMatt Spinler  * @return The service name
47974c916eSMatt Spinler  */
48f0f02b9aSMatt Spinler std::string getService(const std::string& path, const std::string& interface,
497354ce62SPatrick Williams                        sdbusplus::bus_t& bus, bool logError = true);
50974c916eSMatt Spinler 
51974c916eSMatt Spinler /**
52974c916eSMatt Spinler  * @brief Read a D-Bus property
53974c916eSMatt Spinler  *
54974c916eSMatt Spinler  * @param[in] interface - the interface the property is on
55974c916eSMatt Spinler  * @param[in] propertName - the name of the property
56974c916eSMatt Spinler  * @param[in] path - the D-Bus path
57974c916eSMatt Spinler  * @param[in] service - the D-Bus service
58974c916eSMatt Spinler  * @param[in] bus - the D-Bus object
59974c916eSMatt Spinler  * @param[out] value - filled in with the property value
60974c916eSMatt Spinler  */
61974c916eSMatt Spinler template <typename T>
getProperty(const std::string & interface,const std::string & propertyName,const std::string & path,const std::string & service,sdbusplus::bus_t & bus,T & value)62f0f02b9aSMatt Spinler void getProperty(const std::string& interface, const std::string& propertyName,
63f0f02b9aSMatt Spinler                  const std::string& path, const std::string& service,
647354ce62SPatrick Williams                  sdbusplus::bus_t& bus, T& value)
65974c916eSMatt Spinler {
66abe49418SPatrick Williams     std::variant<T> property;
67974c916eSMatt Spinler 
68f0f02b9aSMatt Spinler     auto method = bus.new_method_call(service.c_str(), path.c_str(),
69f0f02b9aSMatt Spinler                                       PROPERTY_INTF, "Get");
70974c916eSMatt Spinler 
71974c916eSMatt Spinler     method.append(interface, propertyName);
72974c916eSMatt Spinler 
73974c916eSMatt Spinler     auto reply = bus.call(method);
74974c916eSMatt Spinler 
75974c916eSMatt Spinler     reply.read(property);
76365d61c6SPatrick Williams     value = std::get<T>(property);
77974c916eSMatt Spinler }
78974c916eSMatt Spinler 
7948b4a430SMatt Spinler /**
800a4f519bSBrandon Wyman  * @brief Write a D-Bus property
810a4f519bSBrandon Wyman  *
820a4f519bSBrandon Wyman  * @param[in] interface - the interface the property is on
830a4f519bSBrandon Wyman  * @param[in] propertName - the name of the property
840a4f519bSBrandon Wyman  * @param[in] path - the D-Bus path
850a4f519bSBrandon Wyman  * @param[in] service - the D-Bus service
860a4f519bSBrandon Wyman  * @param[in] bus - the D-Bus object
870a4f519bSBrandon Wyman  * @param[in] value - the value to set the property to
880a4f519bSBrandon Wyman  */
890a4f519bSBrandon Wyman template <typename T>
setProperty(const std::string & interface,const std::string & propertyName,const std::string & path,const std::string & service,sdbusplus::bus_t & bus,T & value)90f0f02b9aSMatt Spinler void setProperty(const std::string& interface, const std::string& propertyName,
91f0f02b9aSMatt Spinler                  const std::string& path, const std::string& service,
927354ce62SPatrick Williams                  sdbusplus::bus_t& bus, T& value)
930a4f519bSBrandon Wyman {
94abe49418SPatrick Williams     std::variant<T> propertyValue(value);
950a4f519bSBrandon Wyman 
96f0f02b9aSMatt Spinler     auto method = bus.new_method_call(service.c_str(), path.c_str(),
97f0f02b9aSMatt Spinler                                       PROPERTY_INTF, "Set");
980a4f519bSBrandon Wyman 
990a4f519bSBrandon Wyman     method.append(interface, propertyName, propertyValue);
1000a4f519bSBrandon Wyman 
1010a4f519bSBrandon Wyman     auto reply = bus.call(method);
1020a4f519bSBrandon Wyman }
1030a4f519bSBrandon Wyman 
1044e8b335eSAdriana Kobylak /**
1054e8b335eSAdriana Kobylak  * @brief Get all D-Bus properties
1064e8b335eSAdriana Kobylak  *
1074e8b335eSAdriana Kobylak  * @param[in] bus - the D-Bus object
1084e8b335eSAdriana Kobylak  * @param[in] path - the D-Bus object path
1094e8b335eSAdriana Kobylak  * @param[in] interface - the D-Bus interface name
1104e8b335eSAdriana Kobylak  * @param[in] service - the D-Bus service name (optional)
1114e8b335eSAdriana Kobylak  *
1124e8b335eSAdriana Kobylak  * @return DbusPropertyMap - Map of property names and values
1134e8b335eSAdriana Kobylak  */
1147354ce62SPatrick Williams DbusPropertyMap getAllProperties(sdbusplus::bus_t& bus, const std::string& path,
1154e8b335eSAdriana Kobylak                                  const std::string& interface,
1164e8b335eSAdriana Kobylak                                  const std::string& service = std::string());
1174e8b335eSAdriana Kobylak 
118c761b5fcSBrandon Wyman /** @brief Get subtree from the object mapper.
119c761b5fcSBrandon Wyman  *
120c761b5fcSBrandon Wyman  * Helper function to find objects, services, and interfaces.
121c761b5fcSBrandon Wyman  * See:
122c761b5fcSBrandon Wyman  * https://github.com/openbmc/docs/blob/master/architecture/object-mapper.md
123c761b5fcSBrandon Wyman  *
124c761b5fcSBrandon Wyman  * @param[in] bus - The D-Bus object.
125c761b5fcSBrandon Wyman  * @param[in] path - The root of the tree to search.
126c761b5fcSBrandon Wyman  * @param[in] interface - Interface in the subtree to search for
127c761b5fcSBrandon Wyman  * @param[in] depth - The number of path elements to descend.
128c761b5fcSBrandon Wyman  *
129c761b5fcSBrandon Wyman  * @return DbusSubtree - Map of object paths to a map of service names to their
130c761b5fcSBrandon Wyman  *                       interfaces.
131c761b5fcSBrandon Wyman  */
1327354ce62SPatrick Williams DbusSubtree getSubTree(sdbusplus::bus_t& bus, const std::string& path,
133c761b5fcSBrandon Wyman                        const std::string& interface, int32_t depth);
134c761b5fcSBrandon Wyman 
1358270b7d1SShawn McCarney /** @brief Get subtree from the object mapper.
1368270b7d1SShawn McCarney  *
1378270b7d1SShawn McCarney  * Helper function to find objects, services, and interfaces.
1388270b7d1SShawn McCarney  * See:
1398270b7d1SShawn McCarney  * https://github.com/openbmc/docs/blob/master/architecture/object-mapper.md
1408270b7d1SShawn McCarney  *
1418270b7d1SShawn McCarney  * @param[in] bus - The D-Bus object.
1428270b7d1SShawn McCarney  * @param[in] path - The root of the tree to search.
1438270b7d1SShawn McCarney  * @param[in] interfaces - Interfaces in the subtree to search for.
1448270b7d1SShawn McCarney  * @param[in] depth - The number of path elements to descend.
1458270b7d1SShawn McCarney  *
1468270b7d1SShawn McCarney  * @return DbusSubtree - Map of object paths to a map of service names to their
1478270b7d1SShawn McCarney  *                       interfaces.
1488270b7d1SShawn McCarney  */
1498270b7d1SShawn McCarney DbusSubtree getSubTree(sdbusplus::bus_t& bus, const std::string& path,
1508270b7d1SShawn McCarney                        const std::vector<std::string>& interfaces,
1518270b7d1SShawn McCarney                        int32_t depth);
1528270b7d1SShawn McCarney 
15306594229SMatt Spinler /** @brief GetAssociatedSubTreePaths wrapper from the object mapper.
15406594229SMatt Spinler  *
15506594229SMatt Spinler  * Helper function to find object paths that implement a certain
15606594229SMatt Spinler  * interface and are also an association endpoint.
15706594229SMatt Spinler  * See:
15806594229SMatt Spinler  * https://github.com/openbmc/docs/blob/master/architecture/object-mapper.md
15906594229SMatt Spinler  *
16006594229SMatt Spinler  * @param[in] bus - The D-Bus object.
16106594229SMatt Spinler  * @param[in] associationPath - The association it must be an endpoint of.
16206594229SMatt Spinler  * @param[in] path - The root of the tree to search.
16306594229SMatt Spinler  * @param[in] interfaces - The interfaces in the subtree to search for
16406594229SMatt Spinler  * @param[in] depth - The number of path elements to descend.
16506594229SMatt Spinler  *
16606594229SMatt Spinler  * @return std::vector<DbusPath> - The object paths.
16706594229SMatt Spinler  */
16806594229SMatt Spinler std::vector<DbusPath> getAssociatedSubTreePaths(
16906594229SMatt Spinler     sdbusplus::bus_t& bus,
17006594229SMatt Spinler     const sdbusplus::message::object_path& associationPath,
17106594229SMatt Spinler     const sdbusplus::message::object_path& path,
17206594229SMatt Spinler     const std::vector<std::string>& interfaces, int32_t depth);
17306594229SMatt Spinler 
1740a4f519bSBrandon Wyman /**
175882ce956SMatt Spinler  * Logs an error and powers off the system.
17648b4a430SMatt Spinler  *
177882ce956SMatt Spinler  * @tparam T - error that will be logged before the power off
17848b4a430SMatt Spinler  * @param[in] bus - D-Bus object
17948b4a430SMatt Spinler  */
180882ce956SMatt Spinler template <typename T>
powerOff(sdbusplus::bus_t & bus)1817354ce62SPatrick Williams void powerOff(sdbusplus::bus_t& bus)
182882ce956SMatt Spinler {
183882ce956SMatt Spinler     phosphor::logging::report<T>();
184882ce956SMatt Spinler 
185f0f02b9aSMatt Spinler     auto method = bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_ROOT,
186f0f02b9aSMatt Spinler                                       SYSTEMD_INTERFACE, "StartUnit");
187882ce956SMatt Spinler 
188882ce956SMatt Spinler     method.append(POWEROFF_TARGET);
189882ce956SMatt Spinler     method.append("replace");
190882ce956SMatt Spinler 
191882ce956SMatt Spinler     bus.call_noreply(method);
192882ce956SMatt Spinler }
19348b4a430SMatt Spinler 
1947dc31bb1SLei YU /**
1957dc31bb1SLei YU  * Load json from a file
1967dc31bb1SLei YU  *
1977dc31bb1SLei YU  * @param[in] path - The path of the json file
1987dc31bb1SLei YU  *
1997dc31bb1SLei YU  * @return The nlohmann::json object
2007dc31bb1SLei YU  */
2017dc31bb1SLei YU nlohmann::json loadJSONFromFile(const char* path);
2027dc31bb1SLei YU 
2034070546eSLei YU /**
2044070546eSLei YU  * Get PmBus access type from the json config
2054070546eSLei YU  *
2064070546eSLei YU  * @param[in] json - The json object
2074070546eSLei YU  *
2084070546eSLei YU  * @return The pmbus access type
2094070546eSLei YU  */
2104070546eSLei YU phosphor::pmbus::Type getPMBusAccessType(const nlohmann::json& json);
2114070546eSLei YU 
212cfc040c7SLei YU /**
213cfc040c7SLei YU  * Check if power is on
214cfc040c7SLei YU  *
215e8c9cd64SLei YU  * @param[in] bus - D-Bus object
216e8c9cd64SLei YU  * @param[in] defaultState - The default state if the function fails to get
217e8c9cd64SLei YU  *                           the power state.
218e8c9cd64SLei YU  *
219e8c9cd64SLei YU  * @return true if power is on, otherwise false;
220e8c9cd64SLei YU  *         defaultState if it fails to get the power state.
221cfc040c7SLei YU  */
2227354ce62SPatrick Williams bool isPoweredOn(sdbusplus::bus_t& bus, bool defaultState = false);
223e8c9cd64SLei YU 
224e8c9cd64SLei YU /**
225e8c9cd64SLei YU  * Get all PSU inventory paths from D-Bus
226e8c9cd64SLei YU  *
227e8c9cd64SLei YU  * @param[in] bus - D-Bus object
228e8c9cd64SLei YU  *
229e8c9cd64SLei YU  * @return The list of PSU inventory paths
230e8c9cd64SLei YU  */
2317354ce62SPatrick Williams std::vector<std::string> getPSUInventoryPaths(sdbusplus::bus_t& bus);
232cfc040c7SLei YU 
233f0f02b9aSMatt Spinler } // namespace util
234f0f02b9aSMatt Spinler } // namespace power
235ab093328SLei YU } // namespace phosphor
236