blob: 3af8defcd7dd00957256c82c08c270636311c5c8 [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"
Hieu Huynhb5190062024-07-11 03:47:21 +000011#include "utils/time_utils.hpp"
George Liua7210022022-10-05 15:44:11 +080012
George Liu34dfcb92022-10-05 16:47:44 +080013#include <boost/system/error_code.hpp>
Ed Tanousef4c65b2023-04-24 15:28:50 -070014#include <boost/url/format.hpp>
15
George Liua7210022022-10-05 15:44:11 +080016#include <memory>
17#include <optional>
18#include <string>
19
20namespace redfish
21{
22
Lakshmi Yadlapati788fe6c2023-06-21 14:39:08 -050023static constexpr std::array<std::string_view, 1> powerSupplyInterface = {
24 "xyz.openbmc_project.Inventory.Item.PowerSupply"};
25
26inline void updatePowerSupplyList(
27 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
28 const std::string& chassisId,
29 const dbus::utility::MapperGetSubTreePathsResponse& powerSupplyPaths)
George Liua7210022022-10-05 15:44:11 +080030{
George Liu00ef5dc2022-10-05 16:27:52 +080031 nlohmann::json& powerSupplyList = asyncResp->res.jsonValue["Members"];
Lakshmi Yadlapati788fe6c2023-06-21 14:39:08 -050032 for (const std::string& powerSupplyPath : powerSupplyPaths)
33 {
34 std::string powerSupplyName =
35 sdbusplus::message::object_path(powerSupplyPath).filename();
36 if (powerSupplyName.empty())
37 {
38 continue;
39 }
40
41 nlohmann::json item = nlohmann::json::object();
42 item["@odata.id"] = boost::urls::format(
43 "/redfish/v1/Chassis/{}/PowerSubsystem/PowerSupplies/{}", chassisId,
44 powerSupplyName);
45
46 powerSupplyList.emplace_back(std::move(item));
47 }
George Liu00ef5dc2022-10-05 16:27:52 +080048 asyncResp->res.jsonValue["Members@odata.count"] = powerSupplyList.size();
George Liua7210022022-10-05 15:44:11 +080049}
50
Lakshmi Yadlapati3e42a322024-06-26 18:28:06 -050051inline void doPowerSupplyCollection(
52 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
53 const std::string& chassisId, const boost::system::error_code& ec,
54 const dbus::utility::MapperGetSubTreePathsResponse& subtreePaths)
George Liua7210022022-10-05 15:44:11 +080055{
Lakshmi Yadlapati3e42a322024-06-26 18:28:06 -050056 if (ec)
George Liua7210022022-10-05 15:44:11 +080057 {
Lakshmi Yadlapati3e42a322024-06-26 18:28:06 -050058 if (ec.value() != EBADR)
59 {
60 BMCWEB_LOG_ERROR("DBUS response error{}", ec.value());
61 messages::internalError(asyncResp->res);
62 }
George Liua7210022022-10-05 15:44:11 +080063 return;
64 }
George Liua7210022022-10-05 15:44:11 +080065 asyncResp->res.addHeader(
66 boost::beast::http::field::link,
67 "</redfish/v1/JsonSchemas/PowerSupplyCollection/PowerSupplyCollection.json>; rel=describedby");
68 asyncResp->res.jsonValue["@odata.type"] =
69 "#PowerSupplyCollection.PowerSupplyCollection";
70 asyncResp->res.jsonValue["Name"] = "Power Supply Collection";
Ed Tanousef4c65b2023-04-24 15:28:50 -070071 asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
72 "/redfish/v1/Chassis/{}/PowerSubsystem/PowerSupplies", chassisId);
George Liua7210022022-10-05 15:44:11 +080073 asyncResp->res.jsonValue["Description"] =
74 "The collection of PowerSupply resource instances.";
George Liu7a2bb2c2023-04-11 10:44:33 +080075 asyncResp->res.jsonValue["Members"] = nlohmann::json::array();
76 asyncResp->res.jsonValue["Members@odata.count"] = 0;
George Liua7210022022-10-05 15:44:11 +080077
Lakshmi Yadlapati3e42a322024-06-26 18:28:06 -050078 updatePowerSupplyList(asyncResp, chassisId, subtreePaths);
George Liua7210022022-10-05 15:44:11 +080079}
80
81inline void handlePowerSupplyCollectionHead(
82 App& app, const crow::Request& req,
83 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
84 const std::string& chassisId)
85{
86 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
87 {
88 return;
89 }
90
91 redfish::chassis_utils::getValidChassisPath(
92 asyncResp, chassisId,
93 [asyncResp,
94 chassisId](const std::optional<std::string>& validChassisPath) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -040095 if (!validChassisPath)
96 {
97 messages::resourceNotFound(asyncResp->res, "Chassis",
98 chassisId);
99 return;
100 }
101 asyncResp->res.addHeader(
102 boost::beast::http::field::link,
103 "</redfish/v1/JsonSchemas/PowerSupplyCollection/PowerSupplyCollection.json>; rel=describedby");
104 });
George Liua7210022022-10-05 15:44:11 +0800105}
106
107inline void handlePowerSupplyCollectionGet(
108 App& app, const crow::Request& req,
109 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
110 const std::string& chassisId)
111{
112 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
113 {
114 return;
115 }
116
Lakshmi Yadlapati3e42a322024-06-26 18:28:06 -0500117 constexpr std::array<std::string_view, 2> chasisInterfaces = {
118 "xyz.openbmc_project.Inventory.Item.Board",
119 "xyz.openbmc_project.Inventory.Item.Chassis"};
120 const std::string reqpath = "/xyz/openbmc_project/inventory";
121
122 dbus::utility::getAssociatedSubTreePathsById(
123 chassisId, reqpath, chasisInterfaces, "powered_by",
124 powerSupplyInterface,
125 [asyncResp, chassisId](
126 const boost::system::error_code& ec,
127 const dbus::utility::MapperGetSubTreePathsResponse& subtreePaths) {
128 doPowerSupplyCollection(asyncResp, chassisId, ec, subtreePaths);
129 });
George Liua7210022022-10-05 15:44:11 +0800130}
131
132inline void requestRoutesPowerSupplyCollection(App& app)
133{
134 BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/PowerSubsystem/PowerSupplies/")
135 .privileges(redfish::privileges::headPowerSupplyCollection)
136 .methods(boost::beast::http::verb::head)(
137 std::bind_front(handlePowerSupplyCollectionHead, std::ref(app)));
138
139 BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/PowerSubsystem/PowerSupplies/")
140 .privileges(redfish::privileges::getPowerSupplyCollection)
141 .methods(boost::beast::http::verb::get)(
142 std::bind_front(handlePowerSupplyCollectionGet, std::ref(app)));
143}
144
Lakshmi Yadlapati3e42a322024-06-26 18:28:06 -0500145inline void afterGetValidPowerSupplyPath(
146 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
147 const std::string& powerSupplyId, const boost::system::error_code& ec,
148 const dbus::utility::MapperGetSubTreeResponse& subtree,
149 const std::function<void(const std::string& powerSupplyPath,
150 const std::string& service)>& callback)
George Liu00ef5dc2022-10-05 16:27:52 +0800151{
Lakshmi Yadlapati3e42a322024-06-26 18:28:06 -0500152 if (ec)
153 {
154 if (ec.value() != EBADR)
155 {
156 BMCWEB_LOG_ERROR("DBUS response error{}", ec.value());
157 messages::internalError(asyncResp->res);
158 }
159 return;
160 }
161 for (const auto& [objectPath, service] : subtree)
162 {
163 sdbusplus::message::object_path path(objectPath);
Myung Baed8e2b612024-10-08 12:19:19 -0500164 if (path.filename() == powerSupplyId)
Lakshmi Yadlapati3e42a322024-06-26 18:28:06 -0500165 {
166 callback(path, service.begin()->first);
167 return;
168 }
169 }
George Liu00ef5dc2022-10-05 16:27:52 +0800170
Lakshmi Yadlapati3e42a322024-06-26 18:28:06 -0500171 BMCWEB_LOG_WARNING("Power supply not found: {}", powerSupplyId);
172 messages::resourceNotFound(asyncResp->res, "PowerSupplies", powerSupplyId);
George Liu00ef5dc2022-10-05 16:27:52 +0800173}
174
George Liu34dfcb92022-10-05 16:47:44 +0800175inline void getValidPowerSupplyPath(
176 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Lakshmi Yadlapati3e42a322024-06-26 18:28:06 -0500177 const std::string& chassisId, const std::string& powerSupplyId,
178 std::function<void(const std::string& powerSupplyPath,
179 const std::string& service)>&& callback)
George Liu00ef5dc2022-10-05 16:27:52 +0800180{
Lakshmi Yadlapati3e42a322024-06-26 18:28:06 -0500181 constexpr std::array<std::string_view, 2> chasisInterfaces = {
182 "xyz.openbmc_project.Inventory.Item.Board",
183 "xyz.openbmc_project.Inventory.Item.Chassis"};
184 const std::string reqpath = "/xyz/openbmc_project/inventory";
185
186 dbus::utility::getAssociatedSubTreeById(
187 chassisId, reqpath, chasisInterfaces, "powered_by",
Lakshmi Yadlapati788fe6c2023-06-21 14:39:08 -0500188 powerSupplyInterface,
Lakshmi Yadlapati3e42a322024-06-26 18:28:06 -0500189 [asyncResp, chassisId, powerSupplyId, callback{std::move(callback)}](
Lakshmi Yadlapati788fe6c2023-06-21 14:39:08 -0500190 const boost::system::error_code& ec,
Lakshmi Yadlapati3e42a322024-06-26 18:28:06 -0500191 const dbus::utility::MapperGetSubTreeResponse& subtree) {
192 afterGetValidPowerSupplyPath(asyncResp, powerSupplyId, ec, subtree,
193 callback);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400194 });
George Liu00ef5dc2022-10-05 16:27:52 +0800195}
196
197inline void
George Liu34dfcb92022-10-05 16:47:44 +0800198 getPowerSupplyState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
199 const std::string& service, const std::string& path)
200{
Ed Tanousdeae6a72024-11-11 21:58:57 -0800201 dbus::utility::getProperty<bool>(
202 service, path, "xyz.openbmc_project.Inventory.Item", "Present",
George Liu34dfcb92022-10-05 16:47:44 +0800203 [asyncResp](const boost::system::error_code& ec, const bool value) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400204 if (ec)
George Liu34dfcb92022-10-05 16:47:44 +0800205 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400206 if (ec.value() != EBADR)
207 {
208 BMCWEB_LOG_ERROR("DBUS response error for State {}",
209 ec.value());
210 messages::internalError(asyncResp->res);
211 }
212 return;
George Liu34dfcb92022-10-05 16:47:44 +0800213 }
George Liu34dfcb92022-10-05 16:47:44 +0800214
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400215 if (!value)
216 {
217 asyncResp->res.jsonValue["Status"]["State"] =
218 resource::State::Absent;
219 }
220 });
George Liu34dfcb92022-10-05 16:47:44 +0800221}
222
223inline void
224 getPowerSupplyHealth(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
225 const std::string& service, const std::string& path)
226{
Ed Tanousdeae6a72024-11-11 21:58:57 -0800227 dbus::utility::getProperty<bool>(
228 service, path, "xyz.openbmc_project.State.Decorator.OperationalStatus",
229 "Functional",
George Liu34dfcb92022-10-05 16:47:44 +0800230 [asyncResp](const boost::system::error_code& ec, const bool value) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400231 if (ec)
George Liu34dfcb92022-10-05 16:47:44 +0800232 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400233 if (ec.value() != EBADR)
234 {
235 BMCWEB_LOG_ERROR("DBUS response error for Health {}",
236 ec.value());
237 messages::internalError(asyncResp->res);
238 }
239 return;
George Liu34dfcb92022-10-05 16:47:44 +0800240 }
George Liu34dfcb92022-10-05 16:47:44 +0800241
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400242 if (!value)
243 {
244 asyncResp->res.jsonValue["Status"]["Health"] =
245 resource::Health::Critical;
246 }
247 });
George Liu34dfcb92022-10-05 16:47:44 +0800248}
249
250inline void
George Liu2b45fb32022-10-05 17:00:00 +0800251 getPowerSupplyAsset(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
252 const std::string& service, const std::string& path)
253{
Ed Tanousdeae6a72024-11-11 21:58:57 -0800254 dbus::utility::getAllProperties(
255 service, path, "xyz.openbmc_project.Inventory.Decorator.Asset",
George Liu2b45fb32022-10-05 17:00:00 +0800256 [asyncResp](const boost::system::error_code& ec,
257 const dbus::utility::DBusPropertiesMap& propertiesList) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400258 if (ec)
George Liu2b45fb32022-10-05 17:00:00 +0800259 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400260 if (ec.value() != EBADR)
261 {
262 BMCWEB_LOG_ERROR("DBUS response error for Asset {}",
263 ec.value());
264 messages::internalError(asyncResp->res);
265 }
266 return;
George Liu2b45fb32022-10-05 17:00:00 +0800267 }
George Liu2b45fb32022-10-05 17:00:00 +0800268
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400269 const std::string* partNumber = nullptr;
270 const std::string* serialNumber = nullptr;
271 const std::string* manufacturer = nullptr;
272 const std::string* model = nullptr;
273 const std::string* sparePartNumber = nullptr;
Hieu Huynhb5190062024-07-11 03:47:21 +0000274 const std::string* buildDate = nullptr;
George Liu2b45fb32022-10-05 17:00:00 +0800275
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400276 const bool success = sdbusplus::unpackPropertiesNoThrow(
277 dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber",
278 partNumber, "SerialNumber", serialNumber, "Manufacturer",
279 manufacturer, "Model", model, "SparePartNumber",
Hieu Huynhb5190062024-07-11 03:47:21 +0000280 sparePartNumber, "BuildDate", buildDate);
George Liu2b45fb32022-10-05 17:00:00 +0800281
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400282 if (!success)
283 {
284 messages::internalError(asyncResp->res);
285 return;
286 }
George Liu2b45fb32022-10-05 17:00:00 +0800287
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400288 if (partNumber != nullptr)
289 {
290 asyncResp->res.jsonValue["PartNumber"] = *partNumber;
291 }
George Liu2b45fb32022-10-05 17:00:00 +0800292
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400293 if (serialNumber != nullptr)
294 {
295 asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
296 }
George Liu2b45fb32022-10-05 17:00:00 +0800297
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400298 if (manufacturer != nullptr)
299 {
300 asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
301 }
George Liu2b45fb32022-10-05 17:00:00 +0800302
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400303 if (model != nullptr)
304 {
305 asyncResp->res.jsonValue["Model"] = *model;
306 }
George Liu2b45fb32022-10-05 17:00:00 +0800307
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400308 // SparePartNumber is optional on D-Bus so skip if it is empty
309 if (sparePartNumber != nullptr && !sparePartNumber->empty())
310 {
311 asyncResp->res.jsonValue["SparePartNumber"] = *sparePartNumber;
312 }
Hieu Huynhb5190062024-07-11 03:47:21 +0000313
314 if (buildDate != nullptr)
315 {
316 time_utils::productionDateReport(asyncResp->res, *buildDate);
317 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400318 });
George Liu2b45fb32022-10-05 17:00:00 +0800319}
320
George Liua0dba872022-10-05 17:03:20 +0800321inline void getPowerSupplyFirmwareVersion(
322 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
323 const std::string& service, const std::string& path)
324{
Ed Tanousdeae6a72024-11-11 21:58:57 -0800325 dbus::utility::getProperty<std::string>(
326 service, path, "xyz.openbmc_project.Software.Version", "Version",
George Liua0dba872022-10-05 17:03:20 +0800327 [asyncResp](const boost::system::error_code& ec,
328 const std::string& value) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400329 if (ec)
George Liua0dba872022-10-05 17:03:20 +0800330 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400331 if (ec.value() != EBADR)
332 {
333 BMCWEB_LOG_ERROR(
334 "DBUS response error for FirmwareVersion {}",
335 ec.value());
336 messages::internalError(asyncResp->res);
337 }
338 return;
George Liua0dba872022-10-05 17:03:20 +0800339 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400340 asyncResp->res.jsonValue["FirmwareVersion"] = value;
341 });
George Liua0dba872022-10-05 17:03:20 +0800342}
343
George Liu2b45fb32022-10-05 17:00:00 +0800344inline void
George Liu44845e52022-10-05 17:09:21 +0800345 getPowerSupplyLocation(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
346 const std::string& service, const std::string& path)
347{
Ed Tanousdeae6a72024-11-11 21:58:57 -0800348 dbus::utility::getProperty<std::string>(
349 service, path, "xyz.openbmc_project.Inventory.Decorator.LocationCode",
350 "LocationCode",
George Liu44845e52022-10-05 17:09:21 +0800351 [asyncResp](const boost::system::error_code& ec,
352 const std::string& value) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400353 if (ec)
George Liu44845e52022-10-05 17:09:21 +0800354 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400355 if (ec.value() != EBADR)
356 {
357 BMCWEB_LOG_ERROR("DBUS response error for Location {}",
358 ec.value());
359 messages::internalError(asyncResp->res);
360 }
361 return;
George Liu44845e52022-10-05 17:09:21 +0800362 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400363 asyncResp->res
364 .jsonValue["Location"]["PartLocation"]["ServiceLabel"] = value;
365 });
George Liu44845e52022-10-05 17:09:21 +0800366}
367
George Liuddceee02022-10-06 08:57:11 +0800368inline void handleGetEfficiencyResponse(
369 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
370 const boost::system::error_code& ec, uint32_t value)
371{
372 if (ec)
373 {
374 if (ec.value() != EBADR)
375 {
Ed Tanous62598e32023-07-17 17:06:25 -0700376 BMCWEB_LOG_ERROR("DBUS response error for DeratingFactor {}",
377 ec.value());
George Liuddceee02022-10-06 08:57:11 +0800378 messages::internalError(asyncResp->res);
379 }
380 return;
381 }
382 // The PDI default value is 0, if it hasn't been set leave off
383 if (value == 0)
384 {
385 return;
386 }
387
388 nlohmann::json::array_t efficiencyRatings;
389 nlohmann::json::object_t efficiencyPercent;
390 efficiencyPercent["EfficiencyPercent"] = value;
391 efficiencyRatings.emplace_back(std::move(efficiencyPercent));
392 asyncResp->res.jsonValue["EfficiencyRatings"] =
393 std::move(efficiencyRatings);
394}
395
396inline void handlePowerSupplyAttributesSubTreeResponse(
397 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
398 const boost::system::error_code& ec,
399 const dbus::utility::MapperGetSubTreeResponse& subtree)
400{
401 if (ec)
402 {
403 if (ec.value() != EBADR)
404 {
Ed Tanous62598e32023-07-17 17:06:25 -0700405 BMCWEB_LOG_ERROR("DBUS response error for EfficiencyPercent {}",
406 ec.value());
George Liuddceee02022-10-06 08:57:11 +0800407 messages::internalError(asyncResp->res);
408 }
409 return;
410 }
411
412 if (subtree.empty())
413 {
Ed Tanous62598e32023-07-17 17:06:25 -0700414 BMCWEB_LOG_DEBUG("Can't find Power Supply Attributes!");
George Liuddceee02022-10-06 08:57:11 +0800415 return;
416 }
417
418 if (subtree.size() != 1)
419 {
Ed Tanous62598e32023-07-17 17:06:25 -0700420 BMCWEB_LOG_ERROR(
421 "Unexpected number of paths returned by getSubTree: {}",
422 subtree.size());
George Liuddceee02022-10-06 08:57:11 +0800423 messages::internalError(asyncResp->res);
424 return;
425 }
426
427 const auto& [path, serviceMap] = *subtree.begin();
428 const auto& [service, interfaces] = *serviceMap.begin();
Ed Tanousdeae6a72024-11-11 21:58:57 -0800429 dbus::utility::getProperty<uint32_t>(
430 service, path, "xyz.openbmc_project.Control.PowerSupplyAttributes",
431 "DeratingFactor",
George Liuddceee02022-10-06 08:57:11 +0800432 [asyncResp](const boost::system::error_code& ec1, uint32_t value) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400433 handleGetEfficiencyResponse(asyncResp, ec1, value);
434 });
George Liuddceee02022-10-06 08:57:11 +0800435}
436
437inline void
438 getEfficiencyPercent(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
439{
440 constexpr std::array<std::string_view, 1> efficiencyIntf = {
441 "xyz.openbmc_project.Control.PowerSupplyAttributes"};
442
443 dbus::utility::getSubTree(
444 "/xyz/openbmc_project", 0, efficiencyIntf,
445 [asyncResp](const boost::system::error_code& ec,
446 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400447 handlePowerSupplyAttributesSubTreeResponse(asyncResp, ec, subtree);
448 });
George Liuddceee02022-10-06 08:57:11 +0800449}
450
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400451inline void doPowerSupplyGet(
452 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
453 const std::string& chassisId, const std::string& powerSupplyId,
Lakshmi Yadlapati3e42a322024-06-26 18:28:06 -0500454 const std::string& powerSupplyPath, const std::string& service)
George Liu00ef5dc2022-10-05 16:27:52 +0800455{
Lakshmi Yadlapati3e42a322024-06-26 18:28:06 -0500456 asyncResp->res.addHeader(
457 boost::beast::http::field::link,
458 "</redfish/v1/JsonSchemas/PowerSupply/PowerSupply.json>; rel=describedby");
459 asyncResp->res.jsonValue["@odata.type"] = "#PowerSupply.v1_5_0.PowerSupply";
460 asyncResp->res.jsonValue["Name"] = "Power Supply";
461 asyncResp->res.jsonValue["Id"] = powerSupplyId;
462 asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
463 "/redfish/v1/Chassis/{}/PowerSubsystem/PowerSupplies/{}", chassisId,
464 powerSupplyId);
George Liu00ef5dc2022-10-05 16:27:52 +0800465
Lakshmi Yadlapati3e42a322024-06-26 18:28:06 -0500466 asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
467 asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK;
George Liu34dfcb92022-10-05 16:47:44 +0800468
Lakshmi Yadlapati3e42a322024-06-26 18:28:06 -0500469 getPowerSupplyState(asyncResp, service, powerSupplyPath);
470 getPowerSupplyHealth(asyncResp, service, powerSupplyPath);
471 getPowerSupplyAsset(asyncResp, service, powerSupplyPath);
472 getPowerSupplyFirmwareVersion(asyncResp, service, powerSupplyPath);
473 getPowerSupplyLocation(asyncResp, service, powerSupplyPath);
474 getEfficiencyPercent(asyncResp);
George Liu00ef5dc2022-10-05 16:27:52 +0800475}
476
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400477inline void handlePowerSupplyHead(
478 App& app, const crow::Request& req,
479 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
480 const std::string& chassisId, const std::string& powerSupplyId)
George Liu00ef5dc2022-10-05 16:27:52 +0800481{
482 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
483 {
484 return;
485 }
486
Lakshmi Yadlapati3e42a322024-06-26 18:28:06 -0500487 // Get the correct Path and Service that match the input parameters
488 getValidPowerSupplyPath(
489 asyncResp, chassisId, powerSupplyId,
490 [asyncResp](const std::string&, const std::string&) {
491 asyncResp->res.addHeader(
492 boost::beast::http::field::link,
493 "</redfish/v1/JsonSchemas/PowerSupply/PowerSupply.json>; rel=describedby");
George Liu00ef5dc2022-10-05 16:27:52 +0800494 });
George Liu00ef5dc2022-10-05 16:27:52 +0800495}
496
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400497inline void handlePowerSupplyGet(
498 App& app, const crow::Request& req,
499 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
500 const std::string& chassisId, const std::string& powerSupplyId)
George Liu00ef5dc2022-10-05 16:27:52 +0800501{
502 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
503 {
504 return;
505 }
Lakshmi Yadlapati3e42a322024-06-26 18:28:06 -0500506 getValidPowerSupplyPath(
507 asyncResp, chassisId, powerSupplyId,
George Liu00ef5dc2022-10-05 16:27:52 +0800508 std::bind_front(doPowerSupplyGet, asyncResp, chassisId, powerSupplyId));
509}
510
511inline void requestRoutesPowerSupply(App& app)
512{
513 BMCWEB_ROUTE(
514 app, "/redfish/v1/Chassis/<str>/PowerSubsystem/PowerSupplies/<str>/")
515 .privileges(redfish::privileges::headPowerSupply)
516 .methods(boost::beast::http::verb::head)(
517 std::bind_front(handlePowerSupplyHead, std::ref(app)));
518
519 BMCWEB_ROUTE(
520 app, "/redfish/v1/Chassis/<str>/PowerSubsystem/PowerSupplies/<str>/")
521 .privileges(redfish::privileges::getPowerSupply)
522 .methods(boost::beast::http::verb::get)(
523 std::bind_front(handlePowerSupplyGet, std::ref(app)));
524}
525
George Liua7210022022-10-05 15:44:11 +0800526} // namespace redfish