blob: 7905885c88d82ef075c02948b245f6c0ffb52cfd [file] [log] [blame]
George Liua7210022022-10-05 15:44:11 +08001#pragma once
2
3#include "app.hpp"
4#include "dbus_utility.hpp"
Ed Tanous539d8c62024-06-19 14:38:27 -07005#include "generated/enums/resource.hpp"
George Liua7210022022-10-05 15:44:11 +08006#include "query.hpp"
7#include "registries/privilege_registry.hpp"
8#include "utils/chassis_utils.hpp"
George Liu2b45fb32022-10-05 17:00:00 +08009#include "utils/dbus_utils.hpp"
10#include "utils/json_utils.hpp"
George Liua7210022022-10-05 15:44:11 +080011
George Liu34dfcb92022-10-05 16:47:44 +080012#include <boost/system/error_code.hpp>
Ed Tanousef4c65b2023-04-24 15:28:50 -070013#include <boost/url/format.hpp>
14
George Liua7210022022-10-05 15:44:11 +080015#include <memory>
16#include <optional>
17#include <string>
18
19namespace redfish
20{
21
Lakshmi Yadlapati788fe6c2023-06-21 14:39:08 -050022static constexpr std::array<std::string_view, 1> powerSupplyInterface = {
23 "xyz.openbmc_project.Inventory.Item.PowerSupply"};
24
25inline void updatePowerSupplyList(
26 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
27 const std::string& chassisId,
28 const dbus::utility::MapperGetSubTreePathsResponse& powerSupplyPaths)
George Liua7210022022-10-05 15:44:11 +080029{
George Liu00ef5dc2022-10-05 16:27:52 +080030 nlohmann::json& powerSupplyList = asyncResp->res.jsonValue["Members"];
Lakshmi Yadlapati788fe6c2023-06-21 14:39:08 -050031 for (const std::string& powerSupplyPath : powerSupplyPaths)
32 {
33 std::string powerSupplyName =
34 sdbusplus::message::object_path(powerSupplyPath).filename();
35 if (powerSupplyName.empty())
36 {
37 continue;
38 }
39
40 nlohmann::json item = nlohmann::json::object();
41 item["@odata.id"] = boost::urls::format(
42 "/redfish/v1/Chassis/{}/PowerSubsystem/PowerSupplies/{}", chassisId,
43 powerSupplyName);
44
45 powerSupplyList.emplace_back(std::move(item));
46 }
George Liu00ef5dc2022-10-05 16:27:52 +080047 asyncResp->res.jsonValue["Members@odata.count"] = powerSupplyList.size();
George Liua7210022022-10-05 15:44:11 +080048}
49
50inline void
51 doPowerSupplyCollection(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
52 const std::string& chassisId,
53 const std::optional<std::string>& validChassisPath)
54{
55 if (!validChassisPath)
56 {
57 messages::resourceNotFound(asyncResp->res, "Chassis", chassisId);
58 return;
59 }
60
61 asyncResp->res.addHeader(
62 boost::beast::http::field::link,
63 "</redfish/v1/JsonSchemas/PowerSupplyCollection/PowerSupplyCollection.json>; rel=describedby");
64 asyncResp->res.jsonValue["@odata.type"] =
65 "#PowerSupplyCollection.PowerSupplyCollection";
66 asyncResp->res.jsonValue["Name"] = "Power Supply Collection";
Ed Tanousef4c65b2023-04-24 15:28:50 -070067 asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
68 "/redfish/v1/Chassis/{}/PowerSubsystem/PowerSupplies", chassisId);
George Liua7210022022-10-05 15:44:11 +080069 asyncResp->res.jsonValue["Description"] =
70 "The collection of PowerSupply resource instances.";
George Liu7a2bb2c2023-04-11 10:44:33 +080071 asyncResp->res.jsonValue["Members"] = nlohmann::json::array();
72 asyncResp->res.jsonValue["Members@odata.count"] = 0;
George Liua7210022022-10-05 15:44:11 +080073
74 std::string powerPath = *validChassisPath + "/powered_by";
Lakshmi Yadlapati788fe6c2023-06-21 14:39:08 -050075 dbus::utility::getAssociatedSubTreePaths(
76 powerPath,
77 sdbusplus::message::object_path("/xyz/openbmc_project/inventory"), 0,
78 powerSupplyInterface,
79 [asyncResp, chassisId](
80 const boost::system::error_code& ec,
81 const dbus::utility::MapperGetSubTreePathsResponse& subtreePaths) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -040082 if (ec)
George Liua7210022022-10-05 15:44:11 +080083 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -040084 if (ec.value() != EBADR)
85 {
86 BMCWEB_LOG_ERROR("DBUS response error{}", ec.value());
87 messages::internalError(asyncResp->res);
88 }
89 return;
George Liua7210022022-10-05 15:44:11 +080090 }
91
Patrick Williamsbd79bce2024-08-16 15:22:20 -040092 updatePowerSupplyList(asyncResp, chassisId, subtreePaths);
93 });
George Liua7210022022-10-05 15:44:11 +080094}
95
96inline void handlePowerSupplyCollectionHead(
97 App& app, const crow::Request& req,
98 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
99 const std::string& chassisId)
100{
101 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
102 {
103 return;
104 }
105
106 redfish::chassis_utils::getValidChassisPath(
107 asyncResp, chassisId,
108 [asyncResp,
109 chassisId](const std::optional<std::string>& validChassisPath) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400110 if (!validChassisPath)
111 {
112 messages::resourceNotFound(asyncResp->res, "Chassis",
113 chassisId);
114 return;
115 }
116 asyncResp->res.addHeader(
117 boost::beast::http::field::link,
118 "</redfish/v1/JsonSchemas/PowerSupplyCollection/PowerSupplyCollection.json>; rel=describedby");
119 });
George Liua7210022022-10-05 15:44:11 +0800120}
121
122inline void handlePowerSupplyCollectionGet(
123 App& app, const crow::Request& req,
124 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
125 const std::string& chassisId)
126{
127 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
128 {
129 return;
130 }
131
132 redfish::chassis_utils::getValidChassisPath(
133 asyncResp, chassisId,
134 std::bind_front(doPowerSupplyCollection, asyncResp, chassisId));
135}
136
137inline void requestRoutesPowerSupplyCollection(App& app)
138{
139 BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/PowerSubsystem/PowerSupplies/")
140 .privileges(redfish::privileges::headPowerSupplyCollection)
141 .methods(boost::beast::http::verb::head)(
142 std::bind_front(handlePowerSupplyCollectionHead, std::ref(app)));
143
144 BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/PowerSubsystem/PowerSupplies/")
145 .privileges(redfish::privileges::getPowerSupplyCollection)
146 .methods(boost::beast::http::verb::get)(
147 std::bind_front(handlePowerSupplyCollectionGet, std::ref(app)));
148}
149
George Liu00ef5dc2022-10-05 16:27:52 +0800150inline bool checkPowerSupplyId(const std::string& powerSupplyPath,
151 const std::string& powerSupplyId)
152{
153 std::string powerSupplyName =
154 sdbusplus::message::object_path(powerSupplyPath).filename();
155
156 return !(powerSupplyName.empty() || powerSupplyName != powerSupplyId);
157}
158
George Liu34dfcb92022-10-05 16:47:44 +0800159inline void getValidPowerSupplyPath(
160 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
161 const std::string& validChassisPath, const std::string& powerSupplyId,
162 std::function<void(const std::string& powerSupplyPath)>&& callback)
George Liu00ef5dc2022-10-05 16:27:52 +0800163{
164 std::string powerPath = validChassisPath + "/powered_by";
Lakshmi Yadlapati788fe6c2023-06-21 14:39:08 -0500165 dbus::utility::getAssociatedSubTreePaths(
166 powerPath,
167 sdbusplus::message::object_path("/xyz/openbmc_project/inventory"), 0,
168 powerSupplyInterface,
169 [asyncResp, powerSupplyId, callback{std::move(callback)}](
170 const boost::system::error_code& ec,
171 const dbus::utility::MapperGetSubTreePathsResponse& subtreePaths) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400172 if (ec)
George Liu00ef5dc2022-10-05 16:27:52 +0800173 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400174 if (ec.value() != EBADR)
175 {
176 BMCWEB_LOG_ERROR(
177 "DBUS response error for getAssociatedSubTreePaths{}",
178 ec.value());
179 messages::internalError(asyncResp->res);
180 return;
181 }
182 messages::resourceNotFound(asyncResp->res, "PowerSupplies",
183 powerSupplyId);
George Liu00ef5dc2022-10-05 16:27:52 +0800184 return;
185 }
186
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400187 for (const std::string& path : subtreePaths)
George Liu00ef5dc2022-10-05 16:27:52 +0800188 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400189 if (checkPowerSupplyId(path, powerSupplyId))
190 {
191 callback(path);
192 return;
193 }
194 }
195
196 if (!subtreePaths.empty())
197 {
198 BMCWEB_LOG_WARNING("Power supply not found: {}", powerSupplyId);
199 messages::resourceNotFound(asyncResp->res, "PowerSupplies",
200 powerSupplyId);
George Liu00ef5dc2022-10-05 16:27:52 +0800201 return;
202 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400203 });
George Liu00ef5dc2022-10-05 16:27:52 +0800204}
205
206inline void
George Liu34dfcb92022-10-05 16:47:44 +0800207 getPowerSupplyState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
208 const std::string& service, const std::string& path)
209{
210 sdbusplus::asio::getProperty<bool>(
211 *crow::connections::systemBus, service, path,
212 "xyz.openbmc_project.Inventory.Item", "Present",
213 [asyncResp](const boost::system::error_code& ec, const bool value) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400214 if (ec)
George Liu34dfcb92022-10-05 16:47:44 +0800215 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400216 if (ec.value() != EBADR)
217 {
218 BMCWEB_LOG_ERROR("DBUS response error for State {}",
219 ec.value());
220 messages::internalError(asyncResp->res);
221 }
222 return;
George Liu34dfcb92022-10-05 16:47:44 +0800223 }
George Liu34dfcb92022-10-05 16:47:44 +0800224
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400225 if (!value)
226 {
227 asyncResp->res.jsonValue["Status"]["State"] =
228 resource::State::Absent;
229 }
230 });
George Liu34dfcb92022-10-05 16:47:44 +0800231}
232
233inline void
234 getPowerSupplyHealth(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
235 const std::string& service, const std::string& path)
236{
237 sdbusplus::asio::getProperty<bool>(
238 *crow::connections::systemBus, service, path,
239 "xyz.openbmc_project.State.Decorator.OperationalStatus", "Functional",
240 [asyncResp](const boost::system::error_code& ec, const bool value) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400241 if (ec)
George Liu34dfcb92022-10-05 16:47:44 +0800242 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400243 if (ec.value() != EBADR)
244 {
245 BMCWEB_LOG_ERROR("DBUS response error for Health {}",
246 ec.value());
247 messages::internalError(asyncResp->res);
248 }
249 return;
George Liu34dfcb92022-10-05 16:47:44 +0800250 }
George Liu34dfcb92022-10-05 16:47:44 +0800251
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400252 if (!value)
253 {
254 asyncResp->res.jsonValue["Status"]["Health"] =
255 resource::Health::Critical;
256 }
257 });
George Liu34dfcb92022-10-05 16:47:44 +0800258}
259
260inline void
George Liu2b45fb32022-10-05 17:00:00 +0800261 getPowerSupplyAsset(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
262 const std::string& service, const std::string& path)
263{
264 sdbusplus::asio::getAllProperties(
265 *crow::connections::systemBus, service, path,
266 "xyz.openbmc_project.Inventory.Decorator.Asset",
267 [asyncResp](const boost::system::error_code& ec,
268 const dbus::utility::DBusPropertiesMap& propertiesList) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400269 if (ec)
George Liu2b45fb32022-10-05 17:00:00 +0800270 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400271 if (ec.value() != EBADR)
272 {
273 BMCWEB_LOG_ERROR("DBUS response error for Asset {}",
274 ec.value());
275 messages::internalError(asyncResp->res);
276 }
277 return;
George Liu2b45fb32022-10-05 17:00:00 +0800278 }
George Liu2b45fb32022-10-05 17:00:00 +0800279
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400280 const std::string* partNumber = nullptr;
281 const std::string* serialNumber = nullptr;
282 const std::string* manufacturer = nullptr;
283 const std::string* model = nullptr;
284 const std::string* sparePartNumber = nullptr;
George Liu2b45fb32022-10-05 17:00:00 +0800285
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400286 const bool success = sdbusplus::unpackPropertiesNoThrow(
287 dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber",
288 partNumber, "SerialNumber", serialNumber, "Manufacturer",
289 manufacturer, "Model", model, "SparePartNumber",
290 sparePartNumber);
George Liu2b45fb32022-10-05 17:00:00 +0800291
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400292 if (!success)
293 {
294 messages::internalError(asyncResp->res);
295 return;
296 }
George Liu2b45fb32022-10-05 17:00:00 +0800297
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400298 if (partNumber != nullptr)
299 {
300 asyncResp->res.jsonValue["PartNumber"] = *partNumber;
301 }
George Liu2b45fb32022-10-05 17:00:00 +0800302
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400303 if (serialNumber != nullptr)
304 {
305 asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
306 }
George Liu2b45fb32022-10-05 17:00:00 +0800307
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400308 if (manufacturer != nullptr)
309 {
310 asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
311 }
George Liu2b45fb32022-10-05 17:00:00 +0800312
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400313 if (model != nullptr)
314 {
315 asyncResp->res.jsonValue["Model"] = *model;
316 }
George Liu2b45fb32022-10-05 17:00:00 +0800317
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400318 // SparePartNumber is optional on D-Bus so skip if it is empty
319 if (sparePartNumber != nullptr && !sparePartNumber->empty())
320 {
321 asyncResp->res.jsonValue["SparePartNumber"] = *sparePartNumber;
322 }
323 });
George Liu2b45fb32022-10-05 17:00:00 +0800324}
325
George Liua0dba872022-10-05 17:03:20 +0800326inline void getPowerSupplyFirmwareVersion(
327 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
328 const std::string& service, const std::string& path)
329{
330 sdbusplus::asio::getProperty<std::string>(
331 *crow::connections::systemBus, service, path,
332 "xyz.openbmc_project.Software.Version", "Version",
333 [asyncResp](const boost::system::error_code& ec,
334 const std::string& value) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400335 if (ec)
George Liua0dba872022-10-05 17:03:20 +0800336 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400337 if (ec.value() != EBADR)
338 {
339 BMCWEB_LOG_ERROR(
340 "DBUS response error for FirmwareVersion {}",
341 ec.value());
342 messages::internalError(asyncResp->res);
343 }
344 return;
George Liua0dba872022-10-05 17:03:20 +0800345 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400346 asyncResp->res.jsonValue["FirmwareVersion"] = value;
347 });
George Liua0dba872022-10-05 17:03:20 +0800348}
349
George Liu2b45fb32022-10-05 17:00:00 +0800350inline void
George Liu44845e52022-10-05 17:09:21 +0800351 getPowerSupplyLocation(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
352 const std::string& service, const std::string& path)
353{
354 sdbusplus::asio::getProperty<std::string>(
355 *crow::connections::systemBus, service, path,
356 "xyz.openbmc_project.Inventory.Decorator.LocationCode", "LocationCode",
357 [asyncResp](const boost::system::error_code& ec,
358 const std::string& value) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400359 if (ec)
George Liu44845e52022-10-05 17:09:21 +0800360 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400361 if (ec.value() != EBADR)
362 {
363 BMCWEB_LOG_ERROR("DBUS response error for Location {}",
364 ec.value());
365 messages::internalError(asyncResp->res);
366 }
367 return;
George Liu44845e52022-10-05 17:09:21 +0800368 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400369 asyncResp->res
370 .jsonValue["Location"]["PartLocation"]["ServiceLabel"] = value;
371 });
George Liu44845e52022-10-05 17:09:21 +0800372}
373
George Liuddceee02022-10-06 08:57:11 +0800374inline void handleGetEfficiencyResponse(
375 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
376 const boost::system::error_code& ec, uint32_t value)
377{
378 if (ec)
379 {
380 if (ec.value() != EBADR)
381 {
Ed Tanous62598e32023-07-17 17:06:25 -0700382 BMCWEB_LOG_ERROR("DBUS response error for DeratingFactor {}",
383 ec.value());
George Liuddceee02022-10-06 08:57:11 +0800384 messages::internalError(asyncResp->res);
385 }
386 return;
387 }
388 // The PDI default value is 0, if it hasn't been set leave off
389 if (value == 0)
390 {
391 return;
392 }
393
394 nlohmann::json::array_t efficiencyRatings;
395 nlohmann::json::object_t efficiencyPercent;
396 efficiencyPercent["EfficiencyPercent"] = value;
397 efficiencyRatings.emplace_back(std::move(efficiencyPercent));
398 asyncResp->res.jsonValue["EfficiencyRatings"] =
399 std::move(efficiencyRatings);
400}
401
402inline void handlePowerSupplyAttributesSubTreeResponse(
403 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
404 const boost::system::error_code& ec,
405 const dbus::utility::MapperGetSubTreeResponse& subtree)
406{
407 if (ec)
408 {
409 if (ec.value() != EBADR)
410 {
Ed Tanous62598e32023-07-17 17:06:25 -0700411 BMCWEB_LOG_ERROR("DBUS response error for EfficiencyPercent {}",
412 ec.value());
George Liuddceee02022-10-06 08:57:11 +0800413 messages::internalError(asyncResp->res);
414 }
415 return;
416 }
417
418 if (subtree.empty())
419 {
Ed Tanous62598e32023-07-17 17:06:25 -0700420 BMCWEB_LOG_DEBUG("Can't find Power Supply Attributes!");
George Liuddceee02022-10-06 08:57:11 +0800421 return;
422 }
423
424 if (subtree.size() != 1)
425 {
Ed Tanous62598e32023-07-17 17:06:25 -0700426 BMCWEB_LOG_ERROR(
427 "Unexpected number of paths returned by getSubTree: {}",
428 subtree.size());
George Liuddceee02022-10-06 08:57:11 +0800429 messages::internalError(asyncResp->res);
430 return;
431 }
432
433 const auto& [path, serviceMap] = *subtree.begin();
434 const auto& [service, interfaces] = *serviceMap.begin();
435 sdbusplus::asio::getProperty<uint32_t>(
436 *crow::connections::systemBus, service, path,
437 "xyz.openbmc_project.Control.PowerSupplyAttributes", "DeratingFactor",
438 [asyncResp](const boost::system::error_code& ec1, uint32_t value) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400439 handleGetEfficiencyResponse(asyncResp, ec1, value);
440 });
George Liuddceee02022-10-06 08:57:11 +0800441}
442
443inline void
444 getEfficiencyPercent(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
445{
446 constexpr std::array<std::string_view, 1> efficiencyIntf = {
447 "xyz.openbmc_project.Control.PowerSupplyAttributes"};
448
449 dbus::utility::getSubTree(
450 "/xyz/openbmc_project", 0, efficiencyIntf,
451 [asyncResp](const boost::system::error_code& ec,
452 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400453 handlePowerSupplyAttributesSubTreeResponse(asyncResp, ec, subtree);
454 });
George Liuddceee02022-10-06 08:57:11 +0800455}
456
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400457inline void doPowerSupplyGet(
458 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
459 const std::string& chassisId, const std::string& powerSupplyId,
460 const std::optional<std::string>& validChassisPath)
George Liu00ef5dc2022-10-05 16:27:52 +0800461{
462 if (!validChassisPath)
463 {
464 messages::resourceNotFound(asyncResp->res, "Chassis", chassisId);
465 return;
466 }
467
468 // Get the correct Path and Service that match the input parameters
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400469 getValidPowerSupplyPath(
470 asyncResp, *validChassisPath, powerSupplyId,
471 [asyncResp, chassisId,
472 powerSupplyId](const std::string& powerSupplyPath) {
473 asyncResp->res.addHeader(
474 boost::beast::http::field::link,
475 "</redfish/v1/JsonSchemas/PowerSupply/PowerSupply.json>; rel=describedby");
476 asyncResp->res.jsonValue["@odata.type"] =
477 "#PowerSupply.v1_5_0.PowerSupply";
478 asyncResp->res.jsonValue["Name"] = "Power Supply";
479 asyncResp->res.jsonValue["Id"] = powerSupplyId;
480 asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
481 "/redfish/v1/Chassis/{}/PowerSubsystem/PowerSupplies/{}",
482 chassisId, powerSupplyId);
George Liu34dfcb92022-10-05 16:47:44 +0800483
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400484 asyncResp->res.jsonValue["Status"]["State"] =
485 resource::State::Enabled;
486 asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK;
George Liu34dfcb92022-10-05 16:47:44 +0800487
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400488 dbus::utility::getDbusObject(
489 powerSupplyPath, powerSupplyInterface,
490 [asyncResp, powerSupplyPath](
491 const boost::system::error_code& ec,
492 const dbus::utility::MapperGetObject& object) {
493 if (ec || object.empty())
494 {
495 messages::internalError(asyncResp->res);
496 return;
497 }
George Liu34dfcb92022-10-05 16:47:44 +0800498
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400499 getPowerSupplyState(asyncResp, object.begin()->first,
500 powerSupplyPath);
501 getPowerSupplyHealth(asyncResp, object.begin()->first,
502 powerSupplyPath);
503 getPowerSupplyAsset(asyncResp, object.begin()->first,
504 powerSupplyPath);
505 getPowerSupplyFirmwareVersion(
506 asyncResp, object.begin()->first, powerSupplyPath);
507 getPowerSupplyLocation(asyncResp, object.begin()->first,
508 powerSupplyPath);
509 });
510
511 getEfficiencyPercent(asyncResp);
Patrick Williams5a39f772023-10-20 11:20:21 -0500512 });
George Liu00ef5dc2022-10-05 16:27:52 +0800513}
514
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400515inline void handlePowerSupplyHead(
516 App& app, const crow::Request& req,
517 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
518 const std::string& chassisId, const std::string& powerSupplyId)
George Liu00ef5dc2022-10-05 16:27:52 +0800519{
520 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
521 {
522 return;
523 }
524
525 redfish::chassis_utils::getValidChassisPath(
526 asyncResp, chassisId,
527 [asyncResp, chassisId,
528 powerSupplyId](const std::optional<std::string>& validChassisPath) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400529 if (!validChassisPath)
530 {
531 messages::resourceNotFound(asyncResp->res, "Chassis",
532 chassisId);
533 return;
534 }
George Liu00ef5dc2022-10-05 16:27:52 +0800535
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400536 // Get the correct Path and Service that match the input parameters
537 getValidPowerSupplyPath(
538 asyncResp, *validChassisPath, powerSupplyId,
539 [asyncResp](const std::string&) {
540 asyncResp->res.addHeader(
541 boost::beast::http::field::link,
542 "</redfish/v1/JsonSchemas/PowerSupply/PowerSupply.json>; rel=describedby");
543 });
George Liu00ef5dc2022-10-05 16:27:52 +0800544 });
George Liu00ef5dc2022-10-05 16:27:52 +0800545}
546
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400547inline void handlePowerSupplyGet(
548 App& app, const crow::Request& req,
549 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
550 const std::string& chassisId, const std::string& powerSupplyId)
George Liu00ef5dc2022-10-05 16:27:52 +0800551{
552 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
553 {
554 return;
555 }
556
557 redfish::chassis_utils::getValidChassisPath(
558 asyncResp, chassisId,
559 std::bind_front(doPowerSupplyGet, asyncResp, chassisId, powerSupplyId));
560}
561
562inline void requestRoutesPowerSupply(App& app)
563{
564 BMCWEB_ROUTE(
565 app, "/redfish/v1/Chassis/<str>/PowerSubsystem/PowerSupplies/<str>/")
566 .privileges(redfish::privileges::headPowerSupply)
567 .methods(boost::beast::http::verb::head)(
568 std::bind_front(handlePowerSupplyHead, std::ref(app)));
569
570 BMCWEB_ROUTE(
571 app, "/redfish/v1/Chassis/<str>/PowerSubsystem/PowerSupplies/<str>/")
572 .privileges(redfish::privileges::getPowerSupply)
573 .methods(boost::beast::http::verb::get)(
574 std::bind_front(handlePowerSupplyGet, std::ref(app)));
575}
576
George Liua7210022022-10-05 15:44:11 +0800577} // namespace redfish