blob: a13f3f1ddc2dafbde2f1c44bcde1de2970b209bf [file] [log] [blame]
Ed Tanous40e9b922024-09-10 13:50:16 -07001// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright OpenBMC Authors
George Liua7210022022-10-05 15:44:11 +08003#pragma once
4
5#include "app.hpp"
6#include "dbus_utility.hpp"
Ed Tanous539d8c62024-06-19 14:38:27 -07007#include "generated/enums/resource.hpp"
George Liua7210022022-10-05 15:44:11 +08008#include "query.hpp"
9#include "registries/privilege_registry.hpp"
10#include "utils/chassis_utils.hpp"
George Liu2b45fb32022-10-05 17:00:00 +080011#include "utils/dbus_utils.hpp"
12#include "utils/json_utils.hpp"
Hieu Huynhb5190062024-07-11 03:47:21 +000013#include "utils/time_utils.hpp"
George Liua7210022022-10-05 15:44:11 +080014
George Liu34dfcb92022-10-05 16:47:44 +080015#include <boost/system/error_code.hpp>
Ed Tanousef4c65b2023-04-24 15:28:50 -070016#include <boost/url/format.hpp>
17
George Liua7210022022-10-05 15:44:11 +080018#include <memory>
19#include <optional>
20#include <string>
21
22namespace redfish
23{
24
Lakshmi Yadlapati788fe6c2023-06-21 14:39:08 -050025static constexpr std::array<std::string_view, 1> powerSupplyInterface = {
26 "xyz.openbmc_project.Inventory.Item.PowerSupply"};
27
28inline void updatePowerSupplyList(
29 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
30 const std::string& chassisId,
31 const dbus::utility::MapperGetSubTreePathsResponse& powerSupplyPaths)
George Liua7210022022-10-05 15:44:11 +080032{
George Liu00ef5dc2022-10-05 16:27:52 +080033 nlohmann::json& powerSupplyList = asyncResp->res.jsonValue["Members"];
Lakshmi Yadlapati788fe6c2023-06-21 14:39:08 -050034 for (const std::string& powerSupplyPath : powerSupplyPaths)
35 {
36 std::string powerSupplyName =
37 sdbusplus::message::object_path(powerSupplyPath).filename();
38 if (powerSupplyName.empty())
39 {
40 continue;
41 }
42
43 nlohmann::json item = nlohmann::json::object();
44 item["@odata.id"] = boost::urls::format(
45 "/redfish/v1/Chassis/{}/PowerSubsystem/PowerSupplies/{}", chassisId,
46 powerSupplyName);
47
48 powerSupplyList.emplace_back(std::move(item));
49 }
George Liu00ef5dc2022-10-05 16:27:52 +080050 asyncResp->res.jsonValue["Members@odata.count"] = powerSupplyList.size();
George Liua7210022022-10-05 15:44:11 +080051}
52
Lakshmi Yadlapati3e42a322024-06-26 18:28:06 -050053inline void doPowerSupplyCollection(
54 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
55 const std::string& chassisId, const boost::system::error_code& ec,
56 const dbus::utility::MapperGetSubTreePathsResponse& subtreePaths)
George Liua7210022022-10-05 15:44:11 +080057{
Lakshmi Yadlapati3e42a322024-06-26 18:28:06 -050058 if (ec)
George Liua7210022022-10-05 15:44:11 +080059 {
Lakshmi Yadlapati3e42a322024-06-26 18:28:06 -050060 if (ec.value() != EBADR)
61 {
62 BMCWEB_LOG_ERROR("DBUS response error{}", ec.value());
63 messages::internalError(asyncResp->res);
64 }
George Liua7210022022-10-05 15:44:11 +080065 return;
66 }
George Liua7210022022-10-05 15:44:11 +080067 asyncResp->res.addHeader(
68 boost::beast::http::field::link,
69 "</redfish/v1/JsonSchemas/PowerSupplyCollection/PowerSupplyCollection.json>; rel=describedby");
70 asyncResp->res.jsonValue["@odata.type"] =
71 "#PowerSupplyCollection.PowerSupplyCollection";
72 asyncResp->res.jsonValue["Name"] = "Power Supply Collection";
Ed Tanousef4c65b2023-04-24 15:28:50 -070073 asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
74 "/redfish/v1/Chassis/{}/PowerSubsystem/PowerSupplies", chassisId);
George Liua7210022022-10-05 15:44:11 +080075 asyncResp->res.jsonValue["Description"] =
76 "The collection of PowerSupply resource instances.";
George Liu7a2bb2c2023-04-11 10:44:33 +080077 asyncResp->res.jsonValue["Members"] = nlohmann::json::array();
78 asyncResp->res.jsonValue["Members@odata.count"] = 0;
George Liua7210022022-10-05 15:44:11 +080079
Lakshmi Yadlapati3e42a322024-06-26 18:28:06 -050080 updatePowerSupplyList(asyncResp, chassisId, subtreePaths);
George Liua7210022022-10-05 15:44:11 +080081}
82
83inline void handlePowerSupplyCollectionHead(
84 App& app, const crow::Request& req,
85 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
86 const std::string& chassisId)
87{
88 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
89 {
90 return;
91 }
92
93 redfish::chassis_utils::getValidChassisPath(
94 asyncResp, chassisId,
95 [asyncResp,
96 chassisId](const std::optional<std::string>& validChassisPath) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -040097 if (!validChassisPath)
98 {
99 messages::resourceNotFound(asyncResp->res, "Chassis",
100 chassisId);
101 return;
102 }
103 asyncResp->res.addHeader(
104 boost::beast::http::field::link,
105 "</redfish/v1/JsonSchemas/PowerSupplyCollection/PowerSupplyCollection.json>; rel=describedby");
106 });
George Liua7210022022-10-05 15:44:11 +0800107}
108
109inline void handlePowerSupplyCollectionGet(
110 App& app, const crow::Request& req,
111 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
112 const std::string& chassisId)
113{
114 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
115 {
116 return;
117 }
118
Lakshmi Yadlapati3e42a322024-06-26 18:28:06 -0500119 constexpr std::array<std::string_view, 2> chasisInterfaces = {
120 "xyz.openbmc_project.Inventory.Item.Board",
121 "xyz.openbmc_project.Inventory.Item.Chassis"};
122 const std::string reqpath = "/xyz/openbmc_project/inventory";
123
124 dbus::utility::getAssociatedSubTreePathsById(
125 chassisId, reqpath, chasisInterfaces, "powered_by",
126 powerSupplyInterface,
127 [asyncResp, chassisId](
128 const boost::system::error_code& ec,
129 const dbus::utility::MapperGetSubTreePathsResponse& subtreePaths) {
130 doPowerSupplyCollection(asyncResp, chassisId, ec, subtreePaths);
131 });
George Liua7210022022-10-05 15:44:11 +0800132}
133
134inline void requestRoutesPowerSupplyCollection(App& app)
135{
136 BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/PowerSubsystem/PowerSupplies/")
137 .privileges(redfish::privileges::headPowerSupplyCollection)
138 .methods(boost::beast::http::verb::head)(
139 std::bind_front(handlePowerSupplyCollectionHead, std::ref(app)));
140
141 BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/PowerSubsystem/PowerSupplies/")
142 .privileges(redfish::privileges::getPowerSupplyCollection)
143 .methods(boost::beast::http::verb::get)(
144 std::bind_front(handlePowerSupplyCollectionGet, std::ref(app)));
145}
146
Lakshmi Yadlapati3e42a322024-06-26 18:28:06 -0500147inline void afterGetValidPowerSupplyPath(
148 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
149 const std::string& powerSupplyId, const boost::system::error_code& ec,
150 const dbus::utility::MapperGetSubTreeResponse& subtree,
151 const std::function<void(const std::string& powerSupplyPath,
152 const std::string& service)>& callback)
George Liu00ef5dc2022-10-05 16:27:52 +0800153{
Lakshmi Yadlapati3e42a322024-06-26 18:28:06 -0500154 if (ec)
155 {
156 if (ec.value() != EBADR)
157 {
158 BMCWEB_LOG_ERROR("DBUS response error{}", ec.value());
159 messages::internalError(asyncResp->res);
160 }
161 return;
162 }
163 for (const auto& [objectPath, service] : subtree)
164 {
165 sdbusplus::message::object_path path(objectPath);
Myung Baed8e2b612024-10-08 12:19:19 -0500166 if (path.filename() == powerSupplyId)
Lakshmi Yadlapati3e42a322024-06-26 18:28:06 -0500167 {
168 callback(path, service.begin()->first);
169 return;
170 }
171 }
George Liu00ef5dc2022-10-05 16:27:52 +0800172
Lakshmi Yadlapati3e42a322024-06-26 18:28:06 -0500173 BMCWEB_LOG_WARNING("Power supply not found: {}", powerSupplyId);
174 messages::resourceNotFound(asyncResp->res, "PowerSupplies", powerSupplyId);
George Liu00ef5dc2022-10-05 16:27:52 +0800175}
176
George Liu34dfcb92022-10-05 16:47:44 +0800177inline void getValidPowerSupplyPath(
178 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Lakshmi Yadlapati3e42a322024-06-26 18:28:06 -0500179 const std::string& chassisId, const std::string& powerSupplyId,
180 std::function<void(const std::string& powerSupplyPath,
181 const std::string& service)>&& callback)
George Liu00ef5dc2022-10-05 16:27:52 +0800182{
Lakshmi Yadlapati3e42a322024-06-26 18:28:06 -0500183 constexpr std::array<std::string_view, 2> chasisInterfaces = {
184 "xyz.openbmc_project.Inventory.Item.Board",
185 "xyz.openbmc_project.Inventory.Item.Chassis"};
186 const std::string reqpath = "/xyz/openbmc_project/inventory";
187
188 dbus::utility::getAssociatedSubTreeById(
189 chassisId, reqpath, chasisInterfaces, "powered_by",
Lakshmi Yadlapati788fe6c2023-06-21 14:39:08 -0500190 powerSupplyInterface,
Lakshmi Yadlapati3e42a322024-06-26 18:28:06 -0500191 [asyncResp, chassisId, powerSupplyId, callback{std::move(callback)}](
Lakshmi Yadlapati788fe6c2023-06-21 14:39:08 -0500192 const boost::system::error_code& ec,
Lakshmi Yadlapati3e42a322024-06-26 18:28:06 -0500193 const dbus::utility::MapperGetSubTreeResponse& subtree) {
194 afterGetValidPowerSupplyPath(asyncResp, powerSupplyId, ec, subtree,
195 callback);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400196 });
George Liu00ef5dc2022-10-05 16:27:52 +0800197}
198
199inline void
George Liu34dfcb92022-10-05 16:47:44 +0800200 getPowerSupplyState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
201 const std::string& service, const std::string& path)
202{
Ed Tanousdeae6a72024-11-11 21:58:57 -0800203 dbus::utility::getProperty<bool>(
204 service, path, "xyz.openbmc_project.Inventory.Item", "Present",
George Liu34dfcb92022-10-05 16:47:44 +0800205 [asyncResp](const boost::system::error_code& ec, const bool value) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400206 if (ec)
George Liu34dfcb92022-10-05 16:47:44 +0800207 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400208 if (ec.value() != EBADR)
209 {
210 BMCWEB_LOG_ERROR("DBUS response error for State {}",
211 ec.value());
212 messages::internalError(asyncResp->res);
213 }
214 return;
George Liu34dfcb92022-10-05 16:47:44 +0800215 }
George Liu34dfcb92022-10-05 16:47:44 +0800216
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400217 if (!value)
218 {
219 asyncResp->res.jsonValue["Status"]["State"] =
220 resource::State::Absent;
221 }
222 });
George Liu34dfcb92022-10-05 16:47:44 +0800223}
224
225inline void
226 getPowerSupplyHealth(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
227 const std::string& service, const std::string& path)
228{
Ed Tanousdeae6a72024-11-11 21:58:57 -0800229 dbus::utility::getProperty<bool>(
230 service, path, "xyz.openbmc_project.State.Decorator.OperationalStatus",
231 "Functional",
George Liu34dfcb92022-10-05 16:47:44 +0800232 [asyncResp](const boost::system::error_code& ec, const bool value) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400233 if (ec)
George Liu34dfcb92022-10-05 16:47:44 +0800234 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400235 if (ec.value() != EBADR)
236 {
237 BMCWEB_LOG_ERROR("DBUS response error for Health {}",
238 ec.value());
239 messages::internalError(asyncResp->res);
240 }
241 return;
George Liu34dfcb92022-10-05 16:47:44 +0800242 }
George Liu34dfcb92022-10-05 16:47:44 +0800243
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400244 if (!value)
245 {
246 asyncResp->res.jsonValue["Status"]["Health"] =
247 resource::Health::Critical;
248 }
249 });
George Liu34dfcb92022-10-05 16:47:44 +0800250}
251
252inline void
George Liu2b45fb32022-10-05 17:00:00 +0800253 getPowerSupplyAsset(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
254 const std::string& service, const std::string& path)
255{
Ed Tanousdeae6a72024-11-11 21:58:57 -0800256 dbus::utility::getAllProperties(
257 service, path, "xyz.openbmc_project.Inventory.Decorator.Asset",
George Liu2b45fb32022-10-05 17:00:00 +0800258 [asyncResp](const boost::system::error_code& ec,
259 const dbus::utility::DBusPropertiesMap& propertiesList) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400260 if (ec)
George Liu2b45fb32022-10-05 17:00:00 +0800261 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400262 if (ec.value() != EBADR)
263 {
264 BMCWEB_LOG_ERROR("DBUS response error for Asset {}",
265 ec.value());
266 messages::internalError(asyncResp->res);
267 }
268 return;
George Liu2b45fb32022-10-05 17:00:00 +0800269 }
George Liu2b45fb32022-10-05 17:00:00 +0800270
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400271 const std::string* partNumber = nullptr;
272 const std::string* serialNumber = nullptr;
273 const std::string* manufacturer = nullptr;
274 const std::string* model = nullptr;
275 const std::string* sparePartNumber = nullptr;
Hieu Huynhb5190062024-07-11 03:47:21 +0000276 const std::string* buildDate = nullptr;
George Liu2b45fb32022-10-05 17:00:00 +0800277
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400278 const bool success = sdbusplus::unpackPropertiesNoThrow(
279 dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber",
280 partNumber, "SerialNumber", serialNumber, "Manufacturer",
281 manufacturer, "Model", model, "SparePartNumber",
Hieu Huynhb5190062024-07-11 03:47:21 +0000282 sparePartNumber, "BuildDate", buildDate);
George Liu2b45fb32022-10-05 17:00:00 +0800283
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400284 if (!success)
285 {
286 messages::internalError(asyncResp->res);
287 return;
288 }
George Liu2b45fb32022-10-05 17:00:00 +0800289
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400290 if (partNumber != nullptr)
291 {
292 asyncResp->res.jsonValue["PartNumber"] = *partNumber;
293 }
George Liu2b45fb32022-10-05 17:00:00 +0800294
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400295 if (serialNumber != nullptr)
296 {
297 asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
298 }
George Liu2b45fb32022-10-05 17:00:00 +0800299
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400300 if (manufacturer != nullptr)
301 {
302 asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
303 }
George Liu2b45fb32022-10-05 17:00:00 +0800304
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400305 if (model != nullptr)
306 {
307 asyncResp->res.jsonValue["Model"] = *model;
308 }
George Liu2b45fb32022-10-05 17:00:00 +0800309
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400310 // SparePartNumber is optional on D-Bus so skip if it is empty
311 if (sparePartNumber != nullptr && !sparePartNumber->empty())
312 {
313 asyncResp->res.jsonValue["SparePartNumber"] = *sparePartNumber;
314 }
Hieu Huynhb5190062024-07-11 03:47:21 +0000315
316 if (buildDate != nullptr)
317 {
318 time_utils::productionDateReport(asyncResp->res, *buildDate);
319 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400320 });
George Liu2b45fb32022-10-05 17:00:00 +0800321}
322
George Liua0dba872022-10-05 17:03:20 +0800323inline void getPowerSupplyFirmwareVersion(
324 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
325 const std::string& service, const std::string& path)
326{
Ed Tanousdeae6a72024-11-11 21:58:57 -0800327 dbus::utility::getProperty<std::string>(
328 service, path, "xyz.openbmc_project.Software.Version", "Version",
George Liua0dba872022-10-05 17:03:20 +0800329 [asyncResp](const boost::system::error_code& ec,
330 const std::string& value) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400331 if (ec)
George Liua0dba872022-10-05 17:03:20 +0800332 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400333 if (ec.value() != EBADR)
334 {
335 BMCWEB_LOG_ERROR(
336 "DBUS response error for FirmwareVersion {}",
337 ec.value());
338 messages::internalError(asyncResp->res);
339 }
340 return;
George Liua0dba872022-10-05 17:03:20 +0800341 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400342 asyncResp->res.jsonValue["FirmwareVersion"] = value;
343 });
George Liua0dba872022-10-05 17:03:20 +0800344}
345
George Liu2b45fb32022-10-05 17:00:00 +0800346inline void
George Liu44845e52022-10-05 17:09:21 +0800347 getPowerSupplyLocation(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
348 const std::string& service, const std::string& path)
349{
Ed Tanousdeae6a72024-11-11 21:58:57 -0800350 dbus::utility::getProperty<std::string>(
351 service, path, "xyz.openbmc_project.Inventory.Decorator.LocationCode",
352 "LocationCode",
George Liu44845e52022-10-05 17:09:21 +0800353 [asyncResp](const boost::system::error_code& ec,
354 const std::string& value) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400355 if (ec)
George Liu44845e52022-10-05 17:09:21 +0800356 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400357 if (ec.value() != EBADR)
358 {
359 BMCWEB_LOG_ERROR("DBUS response error for Location {}",
360 ec.value());
361 messages::internalError(asyncResp->res);
362 }
363 return;
George Liu44845e52022-10-05 17:09:21 +0800364 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400365 asyncResp->res
366 .jsonValue["Location"]["PartLocation"]["ServiceLabel"] = value;
367 });
George Liu44845e52022-10-05 17:09:21 +0800368}
369
George Liuddceee02022-10-06 08:57:11 +0800370inline void handleGetEfficiencyResponse(
371 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
372 const boost::system::error_code& ec, uint32_t value)
373{
374 if (ec)
375 {
376 if (ec.value() != EBADR)
377 {
Ed Tanous62598e32023-07-17 17:06:25 -0700378 BMCWEB_LOG_ERROR("DBUS response error for DeratingFactor {}",
379 ec.value());
George Liuddceee02022-10-06 08:57:11 +0800380 messages::internalError(asyncResp->res);
381 }
382 return;
383 }
384 // The PDI default value is 0, if it hasn't been set leave off
385 if (value == 0)
386 {
387 return;
388 }
389
390 nlohmann::json::array_t efficiencyRatings;
391 nlohmann::json::object_t efficiencyPercent;
392 efficiencyPercent["EfficiencyPercent"] = value;
393 efficiencyRatings.emplace_back(std::move(efficiencyPercent));
394 asyncResp->res.jsonValue["EfficiencyRatings"] =
395 std::move(efficiencyRatings);
396}
397
398inline void handlePowerSupplyAttributesSubTreeResponse(
399 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
400 const boost::system::error_code& ec,
401 const dbus::utility::MapperGetSubTreeResponse& subtree)
402{
403 if (ec)
404 {
405 if (ec.value() != EBADR)
406 {
Ed Tanous62598e32023-07-17 17:06:25 -0700407 BMCWEB_LOG_ERROR("DBUS response error for EfficiencyPercent {}",
408 ec.value());
George Liuddceee02022-10-06 08:57:11 +0800409 messages::internalError(asyncResp->res);
410 }
411 return;
412 }
413
414 if (subtree.empty())
415 {
Ed Tanous62598e32023-07-17 17:06:25 -0700416 BMCWEB_LOG_DEBUG("Can't find Power Supply Attributes!");
George Liuddceee02022-10-06 08:57:11 +0800417 return;
418 }
419
420 if (subtree.size() != 1)
421 {
Ed Tanous62598e32023-07-17 17:06:25 -0700422 BMCWEB_LOG_ERROR(
423 "Unexpected number of paths returned by getSubTree: {}",
424 subtree.size());
George Liuddceee02022-10-06 08:57:11 +0800425 messages::internalError(asyncResp->res);
426 return;
427 }
428
429 const auto& [path, serviceMap] = *subtree.begin();
430 const auto& [service, interfaces] = *serviceMap.begin();
Ed Tanousdeae6a72024-11-11 21:58:57 -0800431 dbus::utility::getProperty<uint32_t>(
432 service, path, "xyz.openbmc_project.Control.PowerSupplyAttributes",
433 "DeratingFactor",
George Liuddceee02022-10-06 08:57:11 +0800434 [asyncResp](const boost::system::error_code& ec1, uint32_t value) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400435 handleGetEfficiencyResponse(asyncResp, ec1, value);
436 });
George Liuddceee02022-10-06 08:57:11 +0800437}
438
439inline void
440 getEfficiencyPercent(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
441{
442 constexpr std::array<std::string_view, 1> efficiencyIntf = {
443 "xyz.openbmc_project.Control.PowerSupplyAttributes"};
444
445 dbus::utility::getSubTree(
446 "/xyz/openbmc_project", 0, efficiencyIntf,
447 [asyncResp](const boost::system::error_code& ec,
448 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400449 handlePowerSupplyAttributesSubTreeResponse(asyncResp, ec, subtree);
450 });
George Liuddceee02022-10-06 08:57:11 +0800451}
452
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400453inline void doPowerSupplyGet(
454 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
455 const std::string& chassisId, const std::string& powerSupplyId,
Lakshmi Yadlapati3e42a322024-06-26 18:28:06 -0500456 const std::string& powerSupplyPath, const std::string& service)
George Liu00ef5dc2022-10-05 16:27:52 +0800457{
Lakshmi Yadlapati3e42a322024-06-26 18:28:06 -0500458 asyncResp->res.addHeader(
459 boost::beast::http::field::link,
460 "</redfish/v1/JsonSchemas/PowerSupply/PowerSupply.json>; rel=describedby");
461 asyncResp->res.jsonValue["@odata.type"] = "#PowerSupply.v1_5_0.PowerSupply";
462 asyncResp->res.jsonValue["Name"] = "Power Supply";
463 asyncResp->res.jsonValue["Id"] = powerSupplyId;
464 asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
465 "/redfish/v1/Chassis/{}/PowerSubsystem/PowerSupplies/{}", chassisId,
466 powerSupplyId);
George Liu00ef5dc2022-10-05 16:27:52 +0800467
Lakshmi Yadlapati3e42a322024-06-26 18:28:06 -0500468 asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
469 asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK;
George Liu34dfcb92022-10-05 16:47:44 +0800470
Lakshmi Yadlapati3e42a322024-06-26 18:28:06 -0500471 getPowerSupplyState(asyncResp, service, powerSupplyPath);
472 getPowerSupplyHealth(asyncResp, service, powerSupplyPath);
473 getPowerSupplyAsset(asyncResp, service, powerSupplyPath);
474 getPowerSupplyFirmwareVersion(asyncResp, service, powerSupplyPath);
475 getPowerSupplyLocation(asyncResp, service, powerSupplyPath);
476 getEfficiencyPercent(asyncResp);
George Liu00ef5dc2022-10-05 16:27:52 +0800477}
478
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400479inline void handlePowerSupplyHead(
480 App& app, const crow::Request& req,
481 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
482 const std::string& chassisId, const std::string& powerSupplyId)
George Liu00ef5dc2022-10-05 16:27:52 +0800483{
484 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
485 {
486 return;
487 }
488
Lakshmi Yadlapati3e42a322024-06-26 18:28:06 -0500489 // Get the correct Path and Service that match the input parameters
490 getValidPowerSupplyPath(
491 asyncResp, chassisId, powerSupplyId,
492 [asyncResp](const std::string&, const std::string&) {
493 asyncResp->res.addHeader(
494 boost::beast::http::field::link,
495 "</redfish/v1/JsonSchemas/PowerSupply/PowerSupply.json>; rel=describedby");
George Liu00ef5dc2022-10-05 16:27:52 +0800496 });
George Liu00ef5dc2022-10-05 16:27:52 +0800497}
498
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400499inline void handlePowerSupplyGet(
500 App& app, const crow::Request& req,
501 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
502 const std::string& chassisId, const std::string& powerSupplyId)
George Liu00ef5dc2022-10-05 16:27:52 +0800503{
504 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
505 {
506 return;
507 }
Lakshmi Yadlapati3e42a322024-06-26 18:28:06 -0500508 getValidPowerSupplyPath(
509 asyncResp, chassisId, powerSupplyId,
George Liu00ef5dc2022-10-05 16:27:52 +0800510 std::bind_front(doPowerSupplyGet, asyncResp, chassisId, powerSupplyId));
511}
512
513inline void requestRoutesPowerSupply(App& app)
514{
515 BMCWEB_ROUTE(
516 app, "/redfish/v1/Chassis/<str>/PowerSubsystem/PowerSupplies/<str>/")
517 .privileges(redfish::privileges::headPowerSupply)
518 .methods(boost::beast::http::verb::head)(
519 std::bind_front(handlePowerSupplyHead, std::ref(app)));
520
521 BMCWEB_ROUTE(
522 app, "/redfish/v1/Chassis/<str>/PowerSubsystem/PowerSupplies/<str>/")
523 .privileges(redfish::privileges::getPowerSupply)
524 .methods(boost::beast::http::verb::get)(
525 std::bind_front(handlePowerSupplyGet, std::ref(app)));
526}
527
George Liua7210022022-10-05 15:44:11 +0800528} // namespace redfish