blob: f4a7d731a63fa253c3ce9caae453f9d8a6c13c43 [file] [log] [blame]
Matt Spinler974c9162017-08-04 08:36:37 -05001#pragma once
2
Lei YU40705462019-10-09 17:07:11 +08003#include "pmbus.hpp"
4
Lei YU7dc31bb2019-08-30 10:07:08 +08005#include <nlohmann/json.hpp>
Matt Spinler882ce952017-10-05 16:12:41 -05006#include <phosphor-logging/elog.hpp>
Anwaar Hadi72e584c2025-05-20 22:02:14 +00007#include <phosphor-logging/lg2.hpp>
Matt Spinler974c9162017-08-04 08:36:37 -05008#include <sdbusplus/bus.hpp>
Brandon Wymand1bc4ce2019-12-13 14:20:34 -06009
Matt Spinler974c9162017-08-04 08:36:37 -050010#include <string>
Shawn McCarney8270b7d2023-06-26 11:35:51 -050011#include <vector>
Matt Spinler974c9162017-08-04 08:36:37 -050012
Lei YUab093322019-10-09 16:43:22 +080013namespace phosphor
Matt Spinler974c9162017-08-04 08:36:37 -050014{
15namespace power
16{
17namespace util
18{
19
Matt Spinlerf0f02b92018-10-25 16:12:43 -050020constexpr auto SYSTEMD_SERVICE = "org.freedesktop.systemd1";
21constexpr auto SYSTEMD_ROOT = "/org/freedesktop/systemd1";
Matt Spinler882ce952017-10-05 16:12:41 -050022constexpr auto SYSTEMD_INTERFACE = "org.freedesktop.systemd1.Manager";
Matt Spinlerf0f02b92018-10-25 16:12:43 -050023constexpr auto POWEROFF_TARGET = "obmc-chassis-hard-poweroff@0.target";
Matt Spinler974c9162017-08-04 08:36:37 -050024constexpr auto PROPERTY_INTF = "org.freedesktop.DBus.Properties";
Faisal Awadaf661ecb2025-07-18 14:03:18 -050025constexpr auto ENTITY_MGR_SERVICE = "xyz.openbmc_project.EntityManager";
Matt Spinler974c9162017-08-04 08:36:37 -050026
Brandon Wymanc761b5f2020-11-05 18:30:41 -060027using DbusPath = std::string;
Adriana Kobylak4e8b3352021-03-16 20:38:50 +000028using DbusProperty = std::string;
Brandon Wymanc761b5f2020-11-05 18:30:41 -060029using DbusService = std::string;
30using DbusInterface = std::string;
31using DbusInterfaceList = std::vector<DbusInterface>;
32using DbusSubtree =
33 std::map<DbusPath, std::map<DbusService, DbusInterfaceList>>;
Adriana Kobylak886574c2021-11-01 18:22:28 +000034using DbusVariant =
Shawn McCarney3cc348c2024-05-29 15:41:31 -050035 std::variant<bool, uint64_t, std::string, std::vector<uint64_t>,
36 std::vector<std::string>>;
Adriana Kobylak4e8b3352021-03-16 20:38:50 +000037using DbusPropertyMap = std::map<DbusProperty, DbusVariant>;
Matt Spinler974c9162017-08-04 08:36:37 -050038/**
39 * @brief Get the service name from the mapper for the
40 * interface and path passed in.
41 *
42 * @param[in] path - the D-Bus path name
43 * @param[in] interface - the D-Bus interface name
44 * @param[in] bus - the D-Bus object
Matthew Barthd2624402020-02-03 15:35:12 -060045 * @param[in] logError - log error when no service found
Matt Spinler974c9162017-08-04 08:36:37 -050046 *
47 * @return The service name
48 */
Matt Spinlerf0f02b92018-10-25 16:12:43 -050049std::string getService(const std::string& path, const std::string& interface,
Patrick Williams7354ce62022-07-22 19:26:56 -050050 sdbusplus::bus_t& bus, bool logError = true);
Matt Spinler974c9162017-08-04 08:36:37 -050051
52/**
53 * @brief Read a D-Bus property
54 *
55 * @param[in] interface - the interface the property is on
56 * @param[in] propertName - the name of the property
57 * @param[in] path - the D-Bus path
58 * @param[in] service - the D-Bus service
59 * @param[in] bus - the D-Bus object
60 * @param[out] value - filled in with the property value
61 */
Matt Spinlerf0f02b92018-10-25 16:12:43 -050062template <typename T>
63void getProperty(const std::string& interface, const std::string& propertyName,
64 const std::string& path, const std::string& service,
Patrick Williams7354ce62022-07-22 19:26:56 -050065 sdbusplus::bus_t& bus, T& value)
Matt Spinler974c9162017-08-04 08:36:37 -050066{
Patrick Williamsabe49412020-05-13 17:59:47 -050067 std::variant<T> property;
Matt Spinler974c9162017-08-04 08:36:37 -050068
Matt Spinlerf0f02b92018-10-25 16:12:43 -050069 auto method = bus.new_method_call(service.c_str(), path.c_str(),
70 PROPERTY_INTF, "Get");
Matt Spinler974c9162017-08-04 08:36:37 -050071
72 method.append(interface, propertyName);
73
74 auto reply = bus.call(method);
Matt Spinler974c9162017-08-04 08:36:37 -050075
76 reply.read(property);
Patrick Williams365d61c2020-05-13 12:23:08 -050077 value = std::get<T>(property);
Matt Spinler974c9162017-08-04 08:36:37 -050078}
79
Matt Spinler48b4a432017-08-04 11:57:37 -050080/**
Brandon Wyman0a4f5192017-12-06 20:19:08 -060081 * @brief Write a D-Bus property
82 *
83 * @param[in] interface - the interface the property is on
84 * @param[in] propertName - the name of the property
85 * @param[in] path - the D-Bus path
86 * @param[in] service - the D-Bus service
87 * @param[in] bus - the D-Bus object
88 * @param[in] value - the value to set the property to
89 */
Matt Spinlerf0f02b92018-10-25 16:12:43 -050090template <typename T>
91void setProperty(const std::string& interface, const std::string& propertyName,
92 const std::string& path, const std::string& service,
Patrick Williams7354ce62022-07-22 19:26:56 -050093 sdbusplus::bus_t& bus, T& value)
Brandon Wyman0a4f5192017-12-06 20:19:08 -060094{
Patrick Williamsabe49412020-05-13 17:59:47 -050095 std::variant<T> propertyValue(value);
Brandon Wyman0a4f5192017-12-06 20:19:08 -060096
Matt Spinlerf0f02b92018-10-25 16:12:43 -050097 auto method = bus.new_method_call(service.c_str(), path.c_str(),
98 PROPERTY_INTF, "Set");
Brandon Wyman0a4f5192017-12-06 20:19:08 -060099
100 method.append(interface, propertyName, propertyValue);
101
102 auto reply = bus.call(method);
Brandon Wyman0a4f5192017-12-06 20:19:08 -0600103}
104
Adriana Kobylak4e8b3352021-03-16 20:38:50 +0000105/**
106 * @brief Get all D-Bus properties
107 *
108 * @param[in] bus - the D-Bus object
109 * @param[in] path - the D-Bus object path
110 * @param[in] interface - the D-Bus interface name
111 * @param[in] service - the D-Bus service name (optional)
112 *
113 * @return DbusPropertyMap - Map of property names and values
114 */
Patrick Williams7354ce62022-07-22 19:26:56 -0500115DbusPropertyMap getAllProperties(sdbusplus::bus_t& bus, const std::string& path,
Adriana Kobylak4e8b3352021-03-16 20:38:50 +0000116 const std::string& interface,
117 const std::string& service = std::string());
118
Brandon Wymanc761b5f2020-11-05 18:30:41 -0600119/** @brief Get subtree from the object mapper.
120 *
121 * Helper function to find objects, services, and interfaces.
122 * See:
123 * https://github.com/openbmc/docs/blob/master/architecture/object-mapper.md
124 *
125 * @param[in] bus - The D-Bus object.
126 * @param[in] path - The root of the tree to search.
127 * @param[in] interface - Interface in the subtree to search for
128 * @param[in] depth - The number of path elements to descend.
129 *
130 * @return DbusSubtree - Map of object paths to a map of service names to their
131 * interfaces.
132 */
Patrick Williams7354ce62022-07-22 19:26:56 -0500133DbusSubtree getSubTree(sdbusplus::bus_t& bus, const std::string& path,
Brandon Wymanc761b5f2020-11-05 18:30:41 -0600134 const std::string& interface, int32_t depth);
135
Shawn McCarney8270b7d2023-06-26 11:35:51 -0500136/** @brief Get subtree from the object mapper.
137 *
138 * Helper function to find objects, services, and interfaces.
139 * See:
140 * https://github.com/openbmc/docs/blob/master/architecture/object-mapper.md
141 *
142 * @param[in] bus - The D-Bus object.
143 * @param[in] path - The root of the tree to search.
144 * @param[in] interfaces - Interfaces in the subtree to search for.
145 * @param[in] depth - The number of path elements to descend.
146 *
147 * @return DbusSubtree - Map of object paths to a map of service names to their
148 * interfaces.
149 */
150DbusSubtree getSubTree(sdbusplus::bus_t& bus, const std::string& path,
151 const std::vector<std::string>& interfaces,
152 int32_t depth);
153
Matt Spinler06594222023-05-01 10:44:43 -0500154/** @brief GetAssociatedSubTreePaths wrapper from the object mapper.
155 *
156 * Helper function to find object paths that implement a certain
157 * interface and are also an association endpoint.
158 * See:
159 * https://github.com/openbmc/docs/blob/master/architecture/object-mapper.md
160 *
161 * @param[in] bus - The D-Bus object.
162 * @param[in] associationPath - The association it must be an endpoint of.
163 * @param[in] path - The root of the tree to search.
164 * @param[in] interfaces - The interfaces in the subtree to search for
165 * @param[in] depth - The number of path elements to descend.
166 *
167 * @return std::vector<DbusPath> - The object paths.
168 */
169std::vector<DbusPath> getAssociatedSubTreePaths(
170 sdbusplus::bus_t& bus,
171 const sdbusplus::message::object_path& associationPath,
172 const sdbusplus::message::object_path& path,
173 const std::vector<std::string>& interfaces, int32_t depth);
174
Brandon Wyman0a4f5192017-12-06 20:19:08 -0600175/**
Matt Spinler882ce952017-10-05 16:12:41 -0500176 * Logs an error and powers off the system.
Matt Spinler48b4a432017-08-04 11:57:37 -0500177 *
Matt Spinler882ce952017-10-05 16:12:41 -0500178 * @tparam T - error that will be logged before the power off
Matt Spinler48b4a432017-08-04 11:57:37 -0500179 * @param[in] bus - D-Bus object
180 */
Matt Spinlerf0f02b92018-10-25 16:12:43 -0500181template <typename T>
Patrick Williams7354ce62022-07-22 19:26:56 -0500182void powerOff(sdbusplus::bus_t& bus)
Matt Spinler882ce952017-10-05 16:12:41 -0500183{
184 phosphor::logging::report<T>();
185
Matt Spinlerf0f02b92018-10-25 16:12:43 -0500186 auto method = bus.new_method_call(SYSTEMD_SERVICE, SYSTEMD_ROOT,
187 SYSTEMD_INTERFACE, "StartUnit");
Matt Spinler882ce952017-10-05 16:12:41 -0500188
189 method.append(POWEROFF_TARGET);
190 method.append("replace");
191
192 bus.call_noreply(method);
193}
Matt Spinler48b4a432017-08-04 11:57:37 -0500194
Lei YU7dc31bb2019-08-30 10:07:08 +0800195/**
196 * Load json from a file
197 *
198 * @param[in] path - The path of the json file
199 *
200 * @return The nlohmann::json object
201 */
202nlohmann::json loadJSONFromFile(const char* path);
203
Lei YU40705462019-10-09 17:07:11 +0800204/**
205 * Get PmBus access type from the json config
206 *
207 * @param[in] json - The json object
208 *
209 * @return The pmbus access type
210 */
211phosphor::pmbus::Type getPMBusAccessType(const nlohmann::json& json);
212
Lei YUcfc040c2019-10-29 17:10:26 +0800213/**
214 * Check if power is on
215 *
Lei YUe8c9cd62019-11-04 14:24:41 +0800216 * @param[in] bus - D-Bus object
217 * @param[in] defaultState - The default state if the function fails to get
218 * the power state.
219 *
220 * @return true if power is on, otherwise false;
221 * defaultState if it fails to get the power state.
Lei YUcfc040c2019-10-29 17:10:26 +0800222 */
Patrick Williams7354ce62022-07-22 19:26:56 -0500223bool isPoweredOn(sdbusplus::bus_t& bus, bool defaultState = false);
Lei YUe8c9cd62019-11-04 14:24:41 +0800224
225/**
226 * Get all PSU inventory paths from D-Bus
227 *
228 * @param[in] bus - D-Bus object
229 *
230 * @return The list of PSU inventory paths
231 */
Patrick Williams7354ce62022-07-22 19:26:56 -0500232std::vector<std::string> getPSUInventoryPaths(sdbusplus::bus_t& bus);
Lei YUcfc040c2019-10-29 17:10:26 +0800233
Faisal Awadaf661ecb2025-07-18 14:03:18 -0500234/**
235 * @detail Get all chassis inventory paths from D-Bus
236 *
237 * @param[in] bus - D-Bus object
238 *
239 * @return The list of chassis inventory paths
240 */
241std::vector<std::string> getChassisInventoryPaths(sdbusplus::bus_t& bus);
242
243/**
244 * @brief Retrieve the chassis ID for the given D-Bus inventory path.
245 * Query the D-Bus interface for inventory object path and retrieve its unique
246 * ID (ID specified by SlotNumber)
247 *
248 * @param[in] bus - D-Bus object
249 * @param[in] path - The inventory manager D-Bus path for a chassis.
250 *
251 * @return uint64_t - Chassis unique ID
252 */
253uint64_t getChassisInventoryUniqueId(sdbusplus::bus_t& bus,
254 const std::string& path);
255/**
256 * @brief Retrieve the parent chassis unique ID from the Entity Manager.
257 * Given a D-Bus object path, this function extracts the parent path (board or
258 * chassis) and retrieve the chassis unique ID from Entity Manager.
259 *
260 * @param[in] bus - D-Bus object
261 * @param[in] path - The EntityManager D-Bus path for hardware within a chassis
262 * or board.
263 *
264 * @return uint64_t - Chassis unique ID
265 *
266 * @note This function assumes the parent object path contains property in
267 * Entity Manager.
268 */
269uint64_t getParentEMUniqueId(sdbusplus::bus_t& bus, const std::string& path);
270
Matt Spinlerf0f02b92018-10-25 16:12:43 -0500271} // namespace util
272} // namespace power
Lei YUab093322019-10-09 16:43:22 +0800273} // namespace phosphor