blob: 31cd1f9a247e15c646055af011ec856cb1078546 [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) {
82 if (ec)
83 {
84 if (ec.value() != EBADR)
George Liua7210022022-10-05 15:44:11 +080085 {
Ed Tanous62598e32023-07-17 17:06:25 -070086 BMCWEB_LOG_ERROR("DBUS response error{}", ec.value());
Lakshmi Yadlapati788fe6c2023-06-21 14:39:08 -050087 messages::internalError(asyncResp->res);
George Liua7210022022-10-05 15:44:11 +080088 }
Lakshmi Yadlapati788fe6c2023-06-21 14:39:08 -050089 return;
90 }
George Liua7210022022-10-05 15:44:11 +080091
Lakshmi Yadlapati788fe6c2023-06-21 14:39:08 -050092 updatePowerSupplyList(asyncResp, chassisId, subtreePaths);
Patrick Williams5a39f772023-10-20 11:20:21 -050093 });
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) {
110 if (!validChassisPath)
111 {
112 messages::resourceNotFound(asyncResp->res, "Chassis", chassisId);
113 return;
114 }
115 asyncResp->res.addHeader(
116 boost::beast::http::field::link,
117 "</redfish/v1/JsonSchemas/PowerSupplyCollection/PowerSupplyCollection.json>; rel=describedby");
Patrick Williams5a39f772023-10-20 11:20:21 -0500118 });
George Liua7210022022-10-05 15:44:11 +0800119}
120
121inline void handlePowerSupplyCollectionGet(
122 App& app, const crow::Request& req,
123 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
124 const std::string& chassisId)
125{
126 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
127 {
128 return;
129 }
130
131 redfish::chassis_utils::getValidChassisPath(
132 asyncResp, chassisId,
133 std::bind_front(doPowerSupplyCollection, asyncResp, chassisId));
134}
135
136inline void requestRoutesPowerSupplyCollection(App& app)
137{
138 BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/PowerSubsystem/PowerSupplies/")
139 .privileges(redfish::privileges::headPowerSupplyCollection)
140 .methods(boost::beast::http::verb::head)(
141 std::bind_front(handlePowerSupplyCollectionHead, std::ref(app)));
142
143 BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/PowerSubsystem/PowerSupplies/")
144 .privileges(redfish::privileges::getPowerSupplyCollection)
145 .methods(boost::beast::http::verb::get)(
146 std::bind_front(handlePowerSupplyCollectionGet, std::ref(app)));
147}
148
George Liu00ef5dc2022-10-05 16:27:52 +0800149inline bool checkPowerSupplyId(const std::string& powerSupplyPath,
150 const std::string& powerSupplyId)
151{
152 std::string powerSupplyName =
153 sdbusplus::message::object_path(powerSupplyPath).filename();
154
155 return !(powerSupplyName.empty() || powerSupplyName != powerSupplyId);
156}
157
George Liu34dfcb92022-10-05 16:47:44 +0800158inline void getValidPowerSupplyPath(
159 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
160 const std::string& validChassisPath, const std::string& powerSupplyId,
161 std::function<void(const std::string& powerSupplyPath)>&& callback)
George Liu00ef5dc2022-10-05 16:27:52 +0800162{
163 std::string powerPath = validChassisPath + "/powered_by";
Lakshmi Yadlapati788fe6c2023-06-21 14:39:08 -0500164 dbus::utility::getAssociatedSubTreePaths(
165 powerPath,
166 sdbusplus::message::object_path("/xyz/openbmc_project/inventory"), 0,
167 powerSupplyInterface,
168 [asyncResp, powerSupplyId, callback{std::move(callback)}](
169 const boost::system::error_code& ec,
170 const dbus::utility::MapperGetSubTreePathsResponse& subtreePaths) {
171 if (ec)
172 {
173 if (ec.value() != EBADR)
George Liu00ef5dc2022-10-05 16:27:52 +0800174 {
Ed Tanous62598e32023-07-17 17:06:25 -0700175 BMCWEB_LOG_ERROR(
176 "DBUS response error for getAssociatedSubTreePaths{}",
177 ec.value());
Lakshmi Yadlapati788fe6c2023-06-21 14:39:08 -0500178 messages::internalError(asyncResp->res);
George Liu00ef5dc2022-10-05 16:27:52 +0800179 return;
180 }
Lakshmi Yadlapati788fe6c2023-06-21 14:39:08 -0500181 messages::resourceNotFound(asyncResp->res, "PowerSupplies",
182 powerSupplyId);
183 return;
184 }
George Liu00ef5dc2022-10-05 16:27:52 +0800185
Lakshmi Yadlapati788fe6c2023-06-21 14:39:08 -0500186 for (const std::string& path : subtreePaths)
187 {
188 if (checkPowerSupplyId(path, powerSupplyId))
George Liu00ef5dc2022-10-05 16:27:52 +0800189 {
Lakshmi Yadlapati788fe6c2023-06-21 14:39:08 -0500190 callback(path);
George Liu00ef5dc2022-10-05 16:27:52 +0800191 return;
192 }
Lakshmi Yadlapati788fe6c2023-06-21 14:39:08 -0500193 }
194
195 if (!subtreePaths.empty())
196 {
Ed Tanous62598e32023-07-17 17:06:25 -0700197 BMCWEB_LOG_WARNING("Power supply not found: {}", powerSupplyId);
Lakshmi Yadlapati788fe6c2023-06-21 14:39:08 -0500198 messages::resourceNotFound(asyncResp->res, "PowerSupplies",
199 powerSupplyId);
200 return;
201 }
Patrick Williams5a39f772023-10-20 11:20:21 -0500202 });
George Liu00ef5dc2022-10-05 16:27:52 +0800203}
204
205inline void
George Liu34dfcb92022-10-05 16:47:44 +0800206 getPowerSupplyState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
207 const std::string& service, const std::string& path)
208{
209 sdbusplus::asio::getProperty<bool>(
210 *crow::connections::systemBus, service, path,
211 "xyz.openbmc_project.Inventory.Item", "Present",
212 [asyncResp](const boost::system::error_code& ec, const bool value) {
213 if (ec)
214 {
215 if (ec.value() != EBADR)
216 {
Ed Tanous62598e32023-07-17 17:06:25 -0700217 BMCWEB_LOG_ERROR("DBUS response error for State {}",
218 ec.value());
George Liu34dfcb92022-10-05 16:47:44 +0800219 messages::internalError(asyncResp->res);
220 }
221 return;
222 }
223
224 if (!value)
225 {
Ed Tanous539d8c62024-06-19 14:38:27 -0700226 asyncResp->res.jsonValue["Status"]["State"] =
227 resource::State::Absent;
George Liu34dfcb92022-10-05 16:47:44 +0800228 }
Patrick Williams5a39f772023-10-20 11:20:21 -0500229 });
George Liu34dfcb92022-10-05 16:47:44 +0800230}
231
232inline void
233 getPowerSupplyHealth(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
234 const std::string& service, const std::string& path)
235{
236 sdbusplus::asio::getProperty<bool>(
237 *crow::connections::systemBus, service, path,
238 "xyz.openbmc_project.State.Decorator.OperationalStatus", "Functional",
239 [asyncResp](const boost::system::error_code& ec, const bool value) {
240 if (ec)
241 {
242 if (ec.value() != EBADR)
243 {
Ed Tanous62598e32023-07-17 17:06:25 -0700244 BMCWEB_LOG_ERROR("DBUS response error for Health {}",
245 ec.value());
George Liu34dfcb92022-10-05 16:47:44 +0800246 messages::internalError(asyncResp->res);
247 }
248 return;
249 }
250
251 if (!value)
252 {
Ed Tanous539d8c62024-06-19 14:38:27 -0700253 asyncResp->res.jsonValue["Status"]["Health"] =
254 resource::Health::Critical;
George Liu34dfcb92022-10-05 16:47:44 +0800255 }
Patrick Williams5a39f772023-10-20 11:20:21 -0500256 });
George Liu34dfcb92022-10-05 16:47:44 +0800257}
258
259inline void
George Liu2b45fb32022-10-05 17:00:00 +0800260 getPowerSupplyAsset(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
261 const std::string& service, const std::string& path)
262{
263 sdbusplus::asio::getAllProperties(
264 *crow::connections::systemBus, service, path,
265 "xyz.openbmc_project.Inventory.Decorator.Asset",
266 [asyncResp](const boost::system::error_code& ec,
267 const dbus::utility::DBusPropertiesMap& propertiesList) {
268 if (ec)
269 {
270 if (ec.value() != EBADR)
271 {
Ed Tanous62598e32023-07-17 17:06:25 -0700272 BMCWEB_LOG_ERROR("DBUS response error for Asset {}",
273 ec.value());
George Liu2b45fb32022-10-05 17:00:00 +0800274 messages::internalError(asyncResp->res);
275 }
276 return;
277 }
278
279 const std::string* partNumber = nullptr;
280 const std::string* serialNumber = nullptr;
281 const std::string* manufacturer = nullptr;
282 const std::string* model = nullptr;
283 const std::string* sparePartNumber = nullptr;
284
285 const bool success = sdbusplus::unpackPropertiesNoThrow(
286 dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber",
287 partNumber, "SerialNumber", serialNumber, "Manufacturer",
288 manufacturer, "Model", model, "SparePartNumber", sparePartNumber);
289
290 if (!success)
291 {
292 messages::internalError(asyncResp->res);
293 return;
294 }
295
296 if (partNumber != nullptr)
297 {
298 asyncResp->res.jsonValue["PartNumber"] = *partNumber;
299 }
300
301 if (serialNumber != nullptr)
302 {
303 asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
304 }
305
306 if (manufacturer != nullptr)
307 {
308 asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
309 }
310
311 if (model != nullptr)
312 {
313 asyncResp->res.jsonValue["Model"] = *model;
314 }
315
316 // SparePartNumber is optional on D-Bus so skip if it is empty
317 if (sparePartNumber != nullptr && !sparePartNumber->empty())
318 {
319 asyncResp->res.jsonValue["SparePartNumber"] = *sparePartNumber;
320 }
Patrick Williams5a39f772023-10-20 11:20:21 -0500321 });
George Liu2b45fb32022-10-05 17:00:00 +0800322}
323
George Liua0dba872022-10-05 17:03:20 +0800324inline void getPowerSupplyFirmwareVersion(
325 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
326 const std::string& service, const std::string& path)
327{
328 sdbusplus::asio::getProperty<std::string>(
329 *crow::connections::systemBus, service, path,
330 "xyz.openbmc_project.Software.Version", "Version",
331 [asyncResp](const boost::system::error_code& ec,
332 const std::string& value) {
333 if (ec)
334 {
335 if (ec.value() != EBADR)
336 {
Ed Tanous62598e32023-07-17 17:06:25 -0700337 BMCWEB_LOG_ERROR("DBUS response error for FirmwareVersion {}",
338 ec.value());
George Liua0dba872022-10-05 17:03:20 +0800339 messages::internalError(asyncResp->res);
340 }
341 return;
342 }
343 asyncResp->res.jsonValue["FirmwareVersion"] = value;
Patrick Williams5a39f772023-10-20 11:20:21 -0500344 });
George Liua0dba872022-10-05 17:03:20 +0800345}
346
George Liu2b45fb32022-10-05 17:00:00 +0800347inline void
George Liu44845e52022-10-05 17:09:21 +0800348 getPowerSupplyLocation(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
349 const std::string& service, const std::string& path)
350{
351 sdbusplus::asio::getProperty<std::string>(
352 *crow::connections::systemBus, service, path,
353 "xyz.openbmc_project.Inventory.Decorator.LocationCode", "LocationCode",
354 [asyncResp](const boost::system::error_code& ec,
355 const std::string& value) {
356 if (ec)
357 {
358 if (ec.value() != EBADR)
359 {
Ed Tanous62598e32023-07-17 17:06:25 -0700360 BMCWEB_LOG_ERROR("DBUS response error for Location {}",
361 ec.value());
George Liu44845e52022-10-05 17:09:21 +0800362 messages::internalError(asyncResp->res);
363 }
364 return;
365 }
366 asyncResp->res.jsonValue["Location"]["PartLocation"]["ServiceLabel"] =
367 value;
Patrick Williams5a39f772023-10-20 11:20:21 -0500368 });
George Liu44845e52022-10-05 17:09:21 +0800369}
370
George Liuddceee02022-10-06 08:57:11 +0800371inline void handleGetEfficiencyResponse(
372 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
373 const boost::system::error_code& ec, uint32_t value)
374{
375 if (ec)
376 {
377 if (ec.value() != EBADR)
378 {
Ed Tanous62598e32023-07-17 17:06:25 -0700379 BMCWEB_LOG_ERROR("DBUS response error for DeratingFactor {}",
380 ec.value());
George Liuddceee02022-10-06 08:57:11 +0800381 messages::internalError(asyncResp->res);
382 }
383 return;
384 }
385 // The PDI default value is 0, if it hasn't been set leave off
386 if (value == 0)
387 {
388 return;
389 }
390
391 nlohmann::json::array_t efficiencyRatings;
392 nlohmann::json::object_t efficiencyPercent;
393 efficiencyPercent["EfficiencyPercent"] = value;
394 efficiencyRatings.emplace_back(std::move(efficiencyPercent));
395 asyncResp->res.jsonValue["EfficiencyRatings"] =
396 std::move(efficiencyRatings);
397}
398
399inline void handlePowerSupplyAttributesSubTreeResponse(
400 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
401 const boost::system::error_code& ec,
402 const dbus::utility::MapperGetSubTreeResponse& subtree)
403{
404 if (ec)
405 {
406 if (ec.value() != EBADR)
407 {
Ed Tanous62598e32023-07-17 17:06:25 -0700408 BMCWEB_LOG_ERROR("DBUS response error for EfficiencyPercent {}",
409 ec.value());
George Liuddceee02022-10-06 08:57:11 +0800410 messages::internalError(asyncResp->res);
411 }
412 return;
413 }
414
415 if (subtree.empty())
416 {
Ed Tanous62598e32023-07-17 17:06:25 -0700417 BMCWEB_LOG_DEBUG("Can't find Power Supply Attributes!");
George Liuddceee02022-10-06 08:57:11 +0800418 return;
419 }
420
421 if (subtree.size() != 1)
422 {
Ed Tanous62598e32023-07-17 17:06:25 -0700423 BMCWEB_LOG_ERROR(
424 "Unexpected number of paths returned by getSubTree: {}",
425 subtree.size());
George Liuddceee02022-10-06 08:57:11 +0800426 messages::internalError(asyncResp->res);
427 return;
428 }
429
430 const auto& [path, serviceMap] = *subtree.begin();
431 const auto& [service, interfaces] = *serviceMap.begin();
432 sdbusplus::asio::getProperty<uint32_t>(
433 *crow::connections::systemBus, service, path,
434 "xyz.openbmc_project.Control.PowerSupplyAttributes", "DeratingFactor",
435 [asyncResp](const boost::system::error_code& ec1, uint32_t value) {
436 handleGetEfficiencyResponse(asyncResp, ec1, value);
Patrick Williams5a39f772023-10-20 11:20:21 -0500437 });
George Liuddceee02022-10-06 08:57:11 +0800438}
439
440inline void
441 getEfficiencyPercent(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
442{
443 constexpr std::array<std::string_view, 1> efficiencyIntf = {
444 "xyz.openbmc_project.Control.PowerSupplyAttributes"};
445
446 dbus::utility::getSubTree(
447 "/xyz/openbmc_project", 0, efficiencyIntf,
448 [asyncResp](const boost::system::error_code& ec,
449 const dbus::utility::MapperGetSubTreeResponse& subtree) {
450 handlePowerSupplyAttributesSubTreeResponse(asyncResp, ec, subtree);
Patrick Williams5a39f772023-10-20 11:20:21 -0500451 });
George Liuddceee02022-10-06 08:57:11 +0800452}
453
George Liu44845e52022-10-05 17:09:21 +0800454inline void
George Liu00ef5dc2022-10-05 16:27:52 +0800455 doPowerSupplyGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
456 const std::string& chassisId,
457 const std::string& powerSupplyId,
458 const std::optional<std::string>& validChassisPath)
459{
460 if (!validChassisPath)
461 {
462 messages::resourceNotFound(asyncResp->res, "Chassis", chassisId);
463 return;
464 }
465
466 // Get the correct Path and Service that match the input parameters
467 getValidPowerSupplyPath(asyncResp, *validChassisPath, powerSupplyId,
George Liu34dfcb92022-10-05 16:47:44 +0800468 [asyncResp, chassisId, powerSupplyId](
469 const std::string& powerSupplyPath) {
George Liu00ef5dc2022-10-05 16:27:52 +0800470 asyncResp->res.addHeader(
471 boost::beast::http::field::link,
472 "</redfish/v1/JsonSchemas/PowerSupply/PowerSupply.json>; rel=describedby");
473 asyncResp->res.jsonValue["@odata.type"] =
474 "#PowerSupply.v1_5_0.PowerSupply";
475 asyncResp->res.jsonValue["Name"] = "Power Supply";
476 asyncResp->res.jsonValue["Id"] = powerSupplyId;
477 asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
478 "/redfish/v1/Chassis/{}/PowerSubsystem/PowerSupplies/{}", chassisId,
479 powerSupplyId);
George Liu34dfcb92022-10-05 16:47:44 +0800480
Ed Tanous539d8c62024-06-19 14:38:27 -0700481 asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
482 asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK;
George Liu34dfcb92022-10-05 16:47:44 +0800483
George Liu34dfcb92022-10-05 16:47:44 +0800484 dbus::utility::getDbusObject(
Lakshmi Yadlapati788fe6c2023-06-21 14:39:08 -0500485 powerSupplyPath, powerSupplyInterface,
George Liu34dfcb92022-10-05 16:47:44 +0800486 [asyncResp,
487 powerSupplyPath](const boost::system::error_code& ec,
488 const dbus::utility::MapperGetObject& object) {
489 if (ec || object.empty())
490 {
491 messages::internalError(asyncResp->res);
492 return;
493 }
494
495 getPowerSupplyState(asyncResp, object.begin()->first,
496 powerSupplyPath);
497 getPowerSupplyHealth(asyncResp, object.begin()->first,
498 powerSupplyPath);
George Liu2b45fb32022-10-05 17:00:00 +0800499 getPowerSupplyAsset(asyncResp, object.begin()->first,
500 powerSupplyPath);
George Liua0dba872022-10-05 17:03:20 +0800501 getPowerSupplyFirmwareVersion(asyncResp, object.begin()->first,
502 powerSupplyPath);
George Liu44845e52022-10-05 17:09:21 +0800503 getPowerSupplyLocation(asyncResp, object.begin()->first,
504 powerSupplyPath);
Patrick Williams5a39f772023-10-20 11:20:21 -0500505 });
George Liuddceee02022-10-06 08:57:11 +0800506
507 getEfficiencyPercent(asyncResp);
George Liu00ef5dc2022-10-05 16:27:52 +0800508 });
509}
510
511inline void
512 handlePowerSupplyHead(App& app, const crow::Request& req,
513 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
514 const std::string& chassisId,
515 const std::string& powerSupplyId)
516{
517 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
518 {
519 return;
520 }
521
522 redfish::chassis_utils::getValidChassisPath(
523 asyncResp, chassisId,
524 [asyncResp, chassisId,
525 powerSupplyId](const std::optional<std::string>& validChassisPath) {
526 if (!validChassisPath)
527 {
528 messages::resourceNotFound(asyncResp->res, "Chassis", chassisId);
529 return;
530 }
531
532 // Get the correct Path and Service that match the input parameters
533 getValidPowerSupplyPath(asyncResp, *validChassisPath, powerSupplyId,
George Liu34dfcb92022-10-05 16:47:44 +0800534 [asyncResp](const std::string&) {
George Liu00ef5dc2022-10-05 16:27:52 +0800535 asyncResp->res.addHeader(
536 boost::beast::http::field::link,
537 "</redfish/v1/JsonSchemas/PowerSupply/PowerSupply.json>; rel=describedby");
538 });
Patrick Williams5a39f772023-10-20 11:20:21 -0500539 });
George Liu00ef5dc2022-10-05 16:27:52 +0800540}
541
542inline void
543 handlePowerSupplyGet(App& app, const crow::Request& req,
544 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
545 const std::string& chassisId,
546 const std::string& powerSupplyId)
547{
548 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
549 {
550 return;
551 }
552
553 redfish::chassis_utils::getValidChassisPath(
554 asyncResp, chassisId,
555 std::bind_front(doPowerSupplyGet, asyncResp, chassisId, powerSupplyId));
556}
557
558inline void requestRoutesPowerSupply(App& app)
559{
560 BMCWEB_ROUTE(
561 app, "/redfish/v1/Chassis/<str>/PowerSubsystem/PowerSupplies/<str>/")
562 .privileges(redfish::privileges::headPowerSupply)
563 .methods(boost::beast::http::verb::head)(
564 std::bind_front(handlePowerSupplyHead, std::ref(app)));
565
566 BMCWEB_ROUTE(
567 app, "/redfish/v1/Chassis/<str>/PowerSubsystem/PowerSupplies/<str>/")
568 .privileges(redfish::privileges::getPowerSupply)
569 .methods(boost::beast::http::verb::get)(
570 std::bind_front(handlePowerSupplyGet, std::ref(app)));
571}
572
George Liua7210022022-10-05 15:44:11 +0800573} // namespace redfish