xref: /openbmc/phosphor-power/utility.hpp (revision b60823fa)
1 #pragma once
2 
3 #include "pmbus.hpp"
4 
5 #include <nlohmann/json.hpp>
6 #include <phosphor-logging/elog.hpp>
7 #include <phosphor-logging/log.hpp>
8 #include <sdbusplus/bus.hpp>
9 
10 #include <string>
11 #include <vector>
12 
13 namespace phosphor
14 {
15 namespace power
16 {
17 namespace util
18 {
19 
20 constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1";
21 constexpr auto SYSTEMD_ROOT = "/org/freedesktop/systemd1";
22 constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager";
23 constexpr auto POWEROFF_TARGET = "obmc-chassis-hard-poweroff@0.target";
24 constexpr auto PROPERTY_INTF = "org.freedesktop.DBus.Properties";
25 
26 using DbusPath = std::string;
27 using DbusProperty = std::string;
28 using DbusService = std::string;
29 using DbusInterface = std::string;
30 using DbusInterfaceList = std::vector<DbusInterface>;
31 using DbusSubtree =
32     std::map<DbusPath, std::map<DbusService, DbusInterfaceList>>;
33 using DbusVariant =
34     std::variant<bool, uint64_t, std::string, std::vector<uint64_t>>;
35 using DbusPropertyMap = std::map<DbusProperty, DbusVariant>;
36 /**
37  * @brief Get the service name from the mapper for the
38  *        interface and path passed in.
39  *
40  * @param[in] path - the D-Bus path name
41  * @param[in] interface - the D-Bus interface name
42  * @param[in] bus - the D-Bus object
43  * @param[in] logError - log error when no service found
44  *
45  * @return The service name
46  */
47 std::string getService(const std::string& path, const std::string& interface,
48                        sdbusplus::bus_t& bus, bool logError = true);
49 
50 /**
51  * @brief Read a D-Bus property
52  *
53  * @param[in] interface - the interface the property is on
54  * @param[in] propertName - the name of the property
55  * @param[in] path - the D-Bus path
56  * @param[in] service - the D-Bus service
57  * @param[in] bus - the D-Bus object
58  * @param[out] value - filled in with the property value
59  */
60 template <typename T>
61 void getProperty(const std::string& interface, const std::string& propertyName,
62                  const std::string& path, const std::string& service,
63                  sdbusplus::bus_t& bus, T& value)
64 {
65     std::variant<T> property;
66 
67     auto method = bus.new_method_call(service.c_str(), path.c_str(),
68                                       PROPERTY_INTF, "Get");
69 
70     method.append(interface, propertyName);
71 
72     auto reply = bus.call(method);
73 
74     reply.read(property);
75     value = std::get<T>(property);
76 }
77 
78 /**
79  * @brief Write a D-Bus property
80  *
81  * @param[in] interface - the interface the property is on
82  * @param[in] propertName - the name of the property
83  * @param[in] path - the D-Bus path
84  * @param[in] service - the D-Bus service
85  * @param[in] bus - the D-Bus object
86  * @param[in] value - the value to set the property to
87  */
88 template <typename T>
89 void setProperty(const std::string& interface, const std::string& propertyName,
90                  const std::string& path, const std::string& service,
91                  sdbusplus::bus_t& bus, T& value)
92 {
93     std::variant<T> propertyValue(value);
94 
95     auto method = bus.new_method_call(service.c_str(), path.c_str(),
96                                       PROPERTY_INTF, "Set");
97 
98     method.append(interface, propertyName, propertyValue);
99 
100     auto reply = bus.call(method);
101 }
102 
103 /**
104  * @brief Get all D-Bus properties
105  *
106  * @param[in] bus - the D-Bus object
107  * @param[in] path - the D-Bus object path
108  * @param[in] interface - the D-Bus interface name
109  * @param[in] service - the D-Bus service name (optional)
110  *
111  * @return DbusPropertyMap - Map of property names and values
112  */
113 DbusPropertyMap getAllProperties(sdbusplus::bus_t& bus, const std::string& path,
114                                  const std::string& interface,
115                                  const std::string& service = std::string());
116 
117 /** @brief Get subtree from the object mapper.
118  *
119  * Helper function to find objects, services, and interfaces.
120  * See:
121  * https://github.com/openbmc/docs/blob/master/architecture/object-mapper.md
122  *
123  * @param[in] bus - The D-Bus object.
124  * @param[in] path - The root of the tree to search.
125  * @param[in] interface - Interface in the subtree to search for
126  * @param[in] depth - The number of path elements to descend.
127  *
128  * @return DbusSubtree - Map of object paths to a map of service names to their
129  *                       interfaces.
130  */
131 DbusSubtree getSubTree(sdbusplus::bus_t& bus, const std::string& path,
132                        const std::string& interface, int32_t depth);
133 
134 /** @brief Get subtree from the object mapper.
135  *
136  * Helper function to find objects, services, and interfaces.
137  * See:
138  * https://github.com/openbmc/docs/blob/master/architecture/object-mapper.md
139  *
140  * @param[in] bus - The D-Bus object.
141  * @param[in] path - The root of the tree to search.
142  * @param[in] interfaces - Interfaces in the subtree to search for.
143  * @param[in] depth - The number of path elements to descend.
144  *
145  * @return DbusSubtree - Map of object paths to a map of service names to their
146  *                       interfaces.
147  */
148 DbusSubtree getSubTree(sdbusplus::bus_t& bus, const std::string& path,
149                        const std::vector<std::string>& interfaces,
150                        int32_t depth);
151 
152 /** @brief GetAssociatedSubTreePaths wrapper from the object mapper.
153  *
154  * Helper function to find object paths that implement a certain
155  * interface and are also an association endpoint.
156  * See:
157  * https://github.com/openbmc/docs/blob/master/architecture/object-mapper.md
158  *
159  * @param[in] bus - The D-Bus object.
160  * @param[in] associationPath - The association it must be an endpoint of.
161  * @param[in] path - The root of the tree to search.
162  * @param[in] interfaces - The interfaces in the subtree to search for
163  * @param[in] depth - The number of path elements to descend.
164  *
165  * @return std::vector<DbusPath> - The object paths.
166  */
167 std::vector<DbusPath> getAssociatedSubTreePaths(
168     sdbusplus::bus_t& bus,
169     const sdbusplus::message::object_path& associationPath,
170     const sdbusplus::message::object_path& path,
171     const std::vector<std::string>& interfaces, int32_t depth);
172 
173 /**
174  * Logs an error and powers off the system.
175  *
176  * @tparam T - error that will be logged before the power off
177  * @param[in] bus - D-Bus object
178  */
179 template <typename T>
180 void powerOff(sdbusplus::bus_t& bus)
181 {
182     phosphor::logging::report<T>();
183 
184     auto method = bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_ROOT,
185                                       SYSTEMD_INTERFACE, "StartUnit");
186 
187     method.append(POWEROFF_TARGET);
188     method.append("replace");
189 
190     bus.call_noreply(method);
191 }
192 
193 /**
194  * Load json from a file
195  *
196  * @param[in] path - The path of the json file
197  *
198  * @return The nlohmann::json object
199  */
200 nlohmann::json loadJSONFromFile(const char* path);
201 
202 /**
203  * Get PmBus access type from the json config
204  *
205  * @param[in] json - The json object
206  *
207  * @return The pmbus access type
208  */
209 phosphor::pmbus::Type getPMBusAccessType(const nlohmann::json& json);
210 
211 /**
212  * Check if power is on
213  *
214  * @param[in] bus - D-Bus object
215  * @param[in] defaultState - The default state if the function fails to get
216  *                           the power state.
217  *
218  * @return true if power is on, otherwise false;
219  *         defaultState if it fails to get the power state.
220  */
221 bool isPoweredOn(sdbusplus::bus_t& bus, bool defaultState = false);
222 
223 /**
224  * Get all PSU inventory paths from D-Bus
225  *
226  * @param[in] bus - D-Bus object
227  *
228  * @return The list of PSU inventory paths
229  */
230 std::vector<std::string> getPSUInventoryPaths(sdbusplus::bus_t& bus);
231 
232 } // namespace util
233 } // namespace power
234 } // namespace phosphor
235