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