blob: 917da895c1166bcc6d4abdaa84654cba9601ad13 [file] [log] [blame]
Ed Tanous40e9b922024-09-10 13:50:16 -07001// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright OpenBMC Authors
3// SPDX-FileCopyrightText: Copyright 2018 Intel Corporation
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -08004
5#pragma once
6
Ed Tanousd7857202025-01-28 15:32:26 -08007#include "bmcweb_config.h"
8
Ed Tanous3ccb3ad2023-01-13 17:40:03 -08009#include "app.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -080010#include "async_resp.hpp"
George Liu7a1dbc42022-12-07 16:03:22 +080011#include "dbus_utility.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -080012#include "error_messages.hpp"
13#include "generated/enums/pcie_device.hpp"
14#include "generated/enums/pcie_slots.hpp"
Ed Tanous539d8c62024-06-19 14:38:27 -070015#include "generated/enums/resource.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -080016#include "http_request.hpp"
17#include "logging.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080018#include "query.hpp"
19#include "registries/privilege_registry.hpp"
Myung Baef7e62c12025-09-07 14:02:08 -050020#include "utils/asset_utils.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080021#include "utils/dbus_utils.hpp"
Lakshmi Yadlapatic49c3292023-04-19 16:42:35 -050022#include "utils/pcie_util.hpp"
Ed Tanous0ec8b832022-03-14 14:56:47 -070023
Ed Tanousd7857202025-01-28 15:32:26 -080024#include <asm-generic/errno.h>
25
26#include <boost/beast/http/field.hpp>
27#include <boost/beast/http/verb.hpp>
Myung Bae9c75bf72023-12-10 16:38:04 -050028#include <boost/system/error_code.hpp>
Ed Tanousef4c65b2023-04-24 15:28:50 -070029#include <boost/url/format.hpp>
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +020030#include <sdbusplus/unpack_properties.hpp>
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -080031
Ed Tanousd7857202025-01-28 15:32:26 -080032#include <array>
33#include <charconv>
34#include <cstddef>
35#include <cstdint>
36#include <format>
37#include <functional>
Myung Bae8c1d0542024-03-12 17:50:48 -050038#include <limits>
Ed Tanousd7857202025-01-28 15:32:26 -080039#include <memory>
40#include <optional>
41#include <string>
42#include <string_view>
43#include <system_error>
44#include <utility>
45#include <variant>
Myung Bae8c1d0542024-03-12 17:50:48 -050046
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -080047namespace redfish
48{
49
Patrick Williams89492a12023-05-10 07:51:34 -050050static constexpr const char* inventoryPath = "/xyz/openbmc_project/inventory";
Lakshmi Yadlapati94c3a102023-04-05 18:11:22 -050051static constexpr std::array<std::string_view, 1> pcieDeviceInterface = {
52 "xyz.openbmc_project.Inventory.Item.PCIeDevice"};
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -050053static constexpr std::array<std::string_view, 1> pcieSlotInterface = {
54 "xyz.openbmc_project.Inventory.Item.PCIeSlot"};
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -080055
Ed Tanous4ff0f1f2024-09-04 17:27:37 -070056inline void handlePCIeDevicePath(
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -060057 const std::string& pcieDeviceId,
Ed Tanousac106bf2023-06-07 09:24:59 -070058 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -060059 const dbus::utility::MapperGetSubTreePathsResponse& pcieDevicePaths,
60 const std::function<void(const std::string& pcieDevicePath,
61 const std::string& service)>& callback)
62
63{
64 for (const std::string& pcieDevicePath : pcieDevicePaths)
65 {
66 std::string pciecDeviceName =
67 sdbusplus::message::object_path(pcieDevicePath).filename();
68 if (pciecDeviceName.empty() || pciecDeviceName != pcieDeviceId)
69 {
70 continue;
71 }
72
73 dbus::utility::getDbusObject(
Konstantin Aladyshev3a58c5a2024-08-05 12:57:13 +030074 pcieDevicePath, pcieDeviceInterface,
Ed Tanousac106bf2023-06-07 09:24:59 -070075 [pcieDevicePath, asyncResp,
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -060076 callback](const boost::system::error_code& ec,
77 const dbus::utility::MapperGetObject& object) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -040078 if (ec || object.empty())
79 {
80 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
81 messages::internalError(asyncResp->res);
82 return;
83 }
84 callback(pcieDevicePath, object.begin()->first);
85 });
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -060086 return;
87 }
88
Ed Tanous62598e32023-07-17 17:06:25 -070089 BMCWEB_LOG_WARNING("PCIe Device not found");
Ed Tanousac106bf2023-06-07 09:24:59 -070090 messages::resourceNotFound(asyncResp->res, "PCIeDevice", pcieDeviceId);
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -060091}
92
Ed Tanous4ff0f1f2024-09-04 17:27:37 -070093inline void getValidPCIeDevicePath(
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -060094 const std::string& pcieDeviceId,
Ed Tanousac106bf2023-06-07 09:24:59 -070095 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -060096 const std::function<void(const std::string& pcieDevicePath,
97 const std::string& service)>& callback)
98{
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -060099 dbus::utility::getSubTreePaths(
Lakshmi Yadlapati94c3a102023-04-05 18:11:22 -0500100 inventoryPath, 0, pcieDeviceInterface,
Ed Tanousac106bf2023-06-07 09:24:59 -0700101 [pcieDeviceId, asyncResp,
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600102 callback](const boost::system::error_code& ec,
103 const dbus::utility::MapperGetSubTreePathsResponse&
104 pcieDevicePaths) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400105 if (ec)
106 {
107 BMCWEB_LOG_ERROR("D-Bus response error on GetSubTree {}", ec);
108 messages::internalError(asyncResp->res);
109 return;
110 }
111 handlePCIeDevicePath(pcieDeviceId, asyncResp, pcieDevicePaths,
112 callback);
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600113 return;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400114 });
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600115}
116
Ed Tanous4ff0f1f2024-09-04 17:27:37 -0700117inline void handlePCIeDeviceCollectionGet(
Lakshmi Yadlapatib38fa2a2023-03-10 16:19:46 -0600118 crow::App& app, const crow::Request& req,
Ed Tanousac106bf2023-06-07 09:24:59 -0700119 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Lakshmi Yadlapatib38fa2a2023-03-10 16:19:46 -0600120 const std::string& systemName)
121{
Ed Tanousac106bf2023-06-07 09:24:59 -0700122 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Lakshmi Yadlapatib38fa2a2023-03-10 16:19:46 -0600123 {
124 return;
125 }
Ed Tanous25b54db2024-04-17 15:40:31 -0700126 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanous7f3e84a2022-12-28 16:22:54 -0800127 {
128 // Option currently returns no systems. TBD
129 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
130 systemName);
131 return;
132 }
Ed Tanous253f11b2024-05-16 09:38:31 -0700133 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Lakshmi Yadlapatib38fa2a2023-03-10 16:19:46 -0600134 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700135 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
136 systemName);
Lakshmi Yadlapatib38fa2a2023-03-10 16:19:46 -0600137 return;
138 }
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600139
Ed Tanousac106bf2023-06-07 09:24:59 -0700140 asyncResp->res.addHeader(boost::beast::http::field::link,
141 "</redfish/v1/JsonSchemas/PCIeDeviceCollection/"
142 "PCIeDeviceCollection.json>; rel=describedby");
143 asyncResp->res.jsonValue["@odata.type"] =
Lakshmi Yadlapatib38fa2a2023-03-10 16:19:46 -0600144 "#PCIeDeviceCollection.PCIeDeviceCollection";
Ed Tanous253f11b2024-05-16 09:38:31 -0700145 asyncResp->res.jsonValue["@odata.id"] = std::format(
146 "/redfish/v1/Systems/{}/PCIeDevices", BMCWEB_REDFISH_SYSTEM_URI_NAME);
Ed Tanousac106bf2023-06-07 09:24:59 -0700147 asyncResp->res.jsonValue["Name"] = "PCIe Device Collection";
148 asyncResp->res.jsonValue["Description"] = "Collection of PCIe Devices";
Lakshmi Yadlapatib38fa2a2023-03-10 16:19:46 -0600149
Lakshmi Yadlapati70c4d542023-06-08 04:37:18 -0500150 pcie_util::getPCIeDeviceList(asyncResp,
151 nlohmann::json::json_pointer("/Members"));
Lakshmi Yadlapatib38fa2a2023-03-10 16:19:46 -0600152}
153
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700154inline void requestRoutesSystemPCIeDeviceCollection(App& app)
Jason M. Billsadbe1922019-10-14 15:44:35 -0700155{
Jason M. Billsadbe1922019-10-14 15:44:35 -0700156 /**
157 * Functions triggers appropriate requests on DBus
158 */
Ed Tanous22d268c2022-05-19 09:39:07 -0700159 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/PCIeDevices/")
Ed Tanoused398212021-06-09 17:05:54 -0700160 .privileges(redfish::privileges::getPCIeDeviceCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700161 .methods(boost::beast::http::verb::get)(
Lakshmi Yadlapatib38fa2a2023-03-10 16:19:46 -0600162 std::bind_front(handlePCIeDeviceCollectionGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700163}
164
Myung Bae9c75bf72023-12-10 16:38:04 -0500165inline void afterGetAssociatedSubTreePaths(
166 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
167 const boost::system::error_code& ec,
168 const dbus::utility::MapperGetSubTreePathsResponse& processorPaths)
169{
170 if (ec)
171 {
172 if (ec.value() == EBADR)
173 {
174 BMCWEB_LOG_DEBUG("No processor association found");
175 return;
176 }
177 BMCWEB_LOG_ERROR("DBUS response error {}", ec.value());
178 messages::internalError(asyncResp->res);
179 return;
180 }
181
182 if (processorPaths.empty())
183 {
184 BMCWEB_LOG_DEBUG("No association found for processor");
185 return;
186 }
187
188 nlohmann::json& processorList =
189 asyncResp->res.jsonValue["Links"]["Processors"];
190 for (const std::string& processorPath : processorPaths)
191 {
192 std::string processorName =
193 sdbusplus::message::object_path(processorPath).filename();
194 if (processorName.empty())
195 {
196 continue;
197 }
198
199 nlohmann::json item = nlohmann::json::object();
200 item["@odata.id"] =
201 boost::urls::format("/redfish/v1/Systems/{}/Processors/{}",
202 BMCWEB_REDFISH_SYSTEM_URI_NAME, processorName);
203 processorList.emplace_back(std::move(item));
204 }
205
206 asyncResp->res.jsonValue["Links"]["Processors@odata.count"] =
207 processorList.size();
208}
209
210inline void linkAssociatedProcessor(
211 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
212 const std::string& pcieDevicePath)
213{
214 constexpr std::array<std::string_view, 2> processorInterfaces = {
215 "xyz.openbmc_project.Inventory.Item.Cpu",
216 "xyz.openbmc_project.Inventory.Item.Accelerator"};
217
218 dbus::utility::getAssociatedSubTreePaths(
219 pcieDevicePath + "/connected_to",
220 sdbusplus::message::object_path("/xyz/openbmc_project/inventory"), 0,
221 processorInterfaces,
222 std::bind_front(afterGetAssociatedSubTreePaths, asyncResp));
223}
224
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500225inline void addPCIeSlotProperties(
226 crow::Response& res, const boost::system::error_code& ec,
227 const dbus::utility::DBusPropertiesMap& pcieSlotProperties)
228{
229 if (ec)
230 {
Ed Tanous62598e32023-07-17 17:06:25 -0700231 BMCWEB_LOG_ERROR("DBUS response error for getAllProperties{}",
232 ec.value());
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500233 messages::internalError(res);
234 return;
235 }
236 std::string generation;
237 size_t lanes = 0;
238 std::string slotType;
239
240 bool success = sdbusplus::unpackPropertiesNoThrow(
241 dbus_utils::UnpackErrorPrinter(), pcieSlotProperties, "Generation",
242 generation, "Lanes", lanes, "SlotType", slotType);
243
244 if (!success)
245 {
246 messages::internalError(res);
247 return;
248 }
249
250 std::optional<pcie_device::PCIeTypes> pcieType =
251 pcie_util::redfishPcieGenerationFromDbus(generation);
252 if (!pcieType)
253 {
Ed Tanous62598e32023-07-17 17:06:25 -0700254 BMCWEB_LOG_WARNING("Unknown PCIeType: {}", generation);
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500255 }
256 else
257 {
258 if (*pcieType == pcie_device::PCIeTypes::Invalid)
259 {
Ed Tanous62598e32023-07-17 17:06:25 -0700260 BMCWEB_LOG_ERROR("Invalid PCIeType: {}", generation);
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500261 messages::internalError(res);
262 return;
263 }
264 res.jsonValue["Slot"]["PCIeType"] = *pcieType;
265 }
266
Konstantin Aladyshev82f80322023-07-10 15:00:38 +0300267 if (lanes != 0)
268 {
269 res.jsonValue["Slot"]["Lanes"] = lanes;
270 }
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500271
272 std::optional<pcie_slots::SlotTypes> redfishSlotType =
273 pcie_util::dbusSlotTypeToRf(slotType);
274 if (!redfishSlotType)
275 {
Ed Tanous62598e32023-07-17 17:06:25 -0700276 BMCWEB_LOG_WARNING("Unknown PCIeSlot Type: {}", slotType);
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500277 }
278 else
279 {
280 if (*redfishSlotType == pcie_slots::SlotTypes::Invalid)
281 {
Ed Tanous62598e32023-07-17 17:06:25 -0700282 BMCWEB_LOG_ERROR("Invalid PCIeSlot type: {}", slotType);
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500283 messages::internalError(res);
284 return;
285 }
286 res.jsonValue["Slot"]["SlotType"] = *redfishSlotType;
287 }
288}
289
290inline void getPCIeDeviceSlotPath(
291 const std::string& pcieDevicePath,
292 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
293 std::function<void(const std::string& pcieDeviceSlot)>&& callback)
294{
295 std::string associationPath = pcieDevicePath + "/contained_by";
296 dbus::utility::getAssociatedSubTreePaths(
297 associationPath, sdbusplus::message::object_path(inventoryPath), 0,
298 pcieSlotInterface,
Ed Tanous8cb2c022024-03-27 16:31:46 -0700299 [callback = std::move(callback), asyncResp, pcieDevicePath](
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500300 const boost::system::error_code& ec,
301 const dbus::utility::MapperGetSubTreePathsResponse& endpoints) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400302 if (ec)
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500303 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400304 if (ec.value() == EBADR)
305 {
306 // Missing association is not an error
307 return;
308 }
309 BMCWEB_LOG_ERROR(
310 "DBUS response error for getAssociatedSubTreePaths {}",
311 ec.value());
312 messages::internalError(asyncResp->res);
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500313 return;
314 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400315 if (endpoints.size() > 1)
316 {
317 BMCWEB_LOG_ERROR(
Gunnar Millsa6bd55b2025-01-13 11:24:00 -0600318 "PCIeDevice {} is associated with more than one PCIeSlot: {}",
319 pcieDevicePath, endpoints.size());
Myung Bae67f0b9c2025-06-23 09:52:37 -0400320 for (const std::string& slotPath : endpoints)
321 {
322 BMCWEB_LOG_ERROR("Invalid PCIeSlotPath: {}", slotPath);
323 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400324 messages::internalError(asyncResp->res);
325 return;
326 }
327 if (endpoints.empty())
328 {
329 // If the device doesn't have an association, return without
330 // PCIe Slot properties
331 BMCWEB_LOG_DEBUG("PCIeDevice is not associated with PCIeSlot");
332 return;
333 }
334 callback(endpoints[0]);
335 });
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500336}
337
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400338inline void afterGetDbusObject(
339 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
340 const std::string& pcieDeviceSlot, const boost::system::error_code& ec,
341 const dbus::utility::MapperGetObject& object)
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500342{
343 if (ec || object.empty())
344 {
Ed Tanous62598e32023-07-17 17:06:25 -0700345 BMCWEB_LOG_ERROR("DBUS response error for getDbusObject {}",
346 ec.value());
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500347 messages::internalError(asyncResp->res);
348 return;
349 }
Ed Tanousdeae6a72024-11-11 21:58:57 -0800350 dbus::utility::getAllProperties(
351 object.begin()->first, pcieDeviceSlot,
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500352 "xyz.openbmc_project.Inventory.Item.PCIeSlot",
353 [asyncResp](
354 const boost::system::error_code& ec2,
355 const dbus::utility::DBusPropertiesMap& pcieSlotProperties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400356 addPCIeSlotProperties(asyncResp->res, ec2, pcieSlotProperties);
357 });
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500358}
359
360inline void afterGetPCIeDeviceSlotPath(
361 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
362 const std::string& pcieDeviceSlot)
363{
364 dbus::utility::getDbusObject(
365 pcieDeviceSlot, pcieSlotInterface,
366 [asyncResp,
367 pcieDeviceSlot](const boost::system::error_code& ec,
368 const dbus::utility::MapperGetObject& object) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400369 afterGetDbusObject(asyncResp, pcieDeviceSlot, ec, object);
370 });
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500371}
372
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400373inline void getPCIeDeviceHealth(
374 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
375 const std::string& pcieDevicePath, const std::string& service)
Lakshmi Yadlapatie164f1b2023-04-12 17:01:34 -0500376{
Ed Tanousdeae6a72024-11-11 21:58:57 -0800377 dbus::utility::getProperty<bool>(
378 service, pcieDevicePath,
Lakshmi Yadlapatie164f1b2023-04-12 17:01:34 -0500379 "xyz.openbmc_project.State.Decorator.OperationalStatus", "Functional",
380 [asyncResp](const boost::system::error_code& ec, const bool value) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400381 if (ec)
Lakshmi Yadlapatie164f1b2023-04-12 17:01:34 -0500382 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400383 if (ec.value() != EBADR)
384 {
385 BMCWEB_LOG_ERROR("DBUS response error for Health {}",
386 ec.value());
387 messages::internalError(asyncResp->res);
388 }
389 return;
Lakshmi Yadlapatie164f1b2023-04-12 17:01:34 -0500390 }
Lakshmi Yadlapatie164f1b2023-04-12 17:01:34 -0500391
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400392 if (!value)
393 {
394 asyncResp->res.jsonValue["Status"]["Health"] =
395 resource::Health::Critical;
396 }
397 });
Lakshmi Yadlapatie164f1b2023-04-12 17:01:34 -0500398}
399
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400400inline void getPCIeDeviceState(
401 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
402 const std::string& pcieDevicePath, const std::string& service)
Lakshmi Yadlapatic6bb3282023-04-12 16:56:49 -0500403{
Ed Tanousdeae6a72024-11-11 21:58:57 -0800404 dbus::utility::getProperty<bool>(
405 service, pcieDevicePath, "xyz.openbmc_project.Inventory.Item",
406 "Present",
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500407 [asyncResp](const boost::system::error_code& ec, bool value) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400408 if (ec)
Lakshmi Yadlapatic6bb3282023-04-12 16:56:49 -0500409 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400410 if (ec.value() != EBADR)
411 {
412 BMCWEB_LOG_ERROR("DBUS response error for State");
413 messages::internalError(asyncResp->res);
414 }
415 return;
Lakshmi Yadlapatic6bb3282023-04-12 16:56:49 -0500416 }
Lakshmi Yadlapatic6bb3282023-04-12 16:56:49 -0500417
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400418 if (!value)
419 {
420 asyncResp->res.jsonValue["Status"]["State"] =
421 resource::State::Absent;
422 }
423 });
Lakshmi Yadlapatic6bb3282023-04-12 16:56:49 -0500424}
425
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600426inline void addPCIeDeviceProperties(
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500427 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
428 const std::string& pcieDeviceId,
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600429 const dbus::utility::DBusPropertiesMap& pcieDevProperties)
430{
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600431 const std::string* generationInUse = nullptr;
Konstantin Aladyshev814bf202023-07-04 16:30:10 +0300432 const std::string* generationSupported = nullptr;
Konstantin Aladyshev9bb0a7f2023-07-04 12:59:34 +0300433 const size_t* lanesInUse = nullptr;
Konstantin Aladyshev814bf202023-07-04 16:30:10 +0300434 const size_t* maxLanes = nullptr;
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600435
436 const bool success = sdbusplus::unpackPropertiesNoThrow(
Ed Tanous609ba4c2023-07-11 09:14:24 -0700437 dbus_utils::UnpackErrorPrinter(), pcieDevProperties, "GenerationInUse",
438 generationInUse, "GenerationSupported", generationSupported,
439 "LanesInUse", lanesInUse, "MaxLanes", maxLanes);
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600440
441 if (!success)
442 {
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500443 messages::internalError(asyncResp->res);
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600444 return;
445 }
446
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600447 if (generationInUse != nullptr)
448 {
449 std::optional<pcie_device::PCIeTypes> redfishGenerationInUse =
Lakshmi Yadlapatic49c3292023-04-19 16:42:35 -0500450 pcie_util::redfishPcieGenerationFromDbus(*generationInUse);
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600451
452 if (!redfishGenerationInUse)
453 {
Ed Tanous62598e32023-07-17 17:06:25 -0700454 BMCWEB_LOG_WARNING("Unknown PCIe Device Generation: {}",
455 *generationInUse);
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600456 }
Lakshmi Yadlapaticf3b4842023-06-27 02:36:53 -0500457 else
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600458 {
Lakshmi Yadlapaticf3b4842023-06-27 02:36:53 -0500459 if (*redfishGenerationInUse == pcie_device::PCIeTypes::Invalid)
460 {
Ed Tanous62598e32023-07-17 17:06:25 -0700461 BMCWEB_LOG_ERROR("Invalid PCIe Device Generation: {}",
462 *generationInUse);
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500463 messages::internalError(asyncResp->res);
Lakshmi Yadlapaticf3b4842023-06-27 02:36:53 -0500464 return;
465 }
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500466 asyncResp->res.jsonValue["PCIeInterface"]["PCIeType"] =
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600467 *redfishGenerationInUse;
468 }
469 }
470
Konstantin Aladyshev814bf202023-07-04 16:30:10 +0300471 if (generationSupported != nullptr)
472 {
473 std::optional<pcie_device::PCIeTypes> redfishGenerationSupported =
474 pcie_util::redfishPcieGenerationFromDbus(*generationSupported);
475
476 if (!redfishGenerationSupported)
477 {
Ed Tanous62598e32023-07-17 17:06:25 -0700478 BMCWEB_LOG_WARNING("Unknown PCIe Device Generation: {}",
479 *generationSupported);
Konstantin Aladyshev814bf202023-07-04 16:30:10 +0300480 }
481 else
482 {
483 if (*redfishGenerationSupported == pcie_device::PCIeTypes::Invalid)
484 {
Ed Tanous62598e32023-07-17 17:06:25 -0700485 BMCWEB_LOG_ERROR("Invalid PCIe Device Generation: {}",
486 *generationSupported);
Konstantin Aladyshev814bf202023-07-04 16:30:10 +0300487 messages::internalError(asyncResp->res);
488 return;
489 }
490 asyncResp->res.jsonValue["PCIeInterface"]["MaxPCIeType"] =
491 *redfishGenerationSupported;
492 }
493 }
494
Myung Bae8c1d0542024-03-12 17:50:48 -0500495 if (lanesInUse != nullptr)
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600496 {
Myung Bae8c1d0542024-03-12 17:50:48 -0500497 if (*lanesInUse == std::numeric_limits<size_t>::max())
498 {
499 // The default value of LanesInUse is "maxint", and the field will
500 // be null if it is a default value.
501 asyncResp->res.jsonValue["PCIeInterface"]["LanesInUse"] = nullptr;
502 }
503 else
504 {
505 asyncResp->res.jsonValue["PCIeInterface"]["LanesInUse"] =
506 *lanesInUse;
507 }
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600508 }
Konstantin Aladyshev814bf202023-07-04 16:30:10 +0300509 // The default value of MaxLanes is 0, and the field will be
510 // left as off if it is a default value.
511 if (maxLanes != nullptr && *maxLanes != 0)
512 {
513 asyncResp->res.jsonValue["PCIeInterface"]["MaxLanes"] = *maxLanes;
514 }
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600515
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500516 asyncResp->res.jsonValue["PCIeFunctions"]["@odata.id"] =
517 boost::urls::format(
Ed Tanous253f11b2024-05-16 09:38:31 -0700518 "/redfish/v1/Systems/{}/PCIeDevices/{}/PCIeFunctions",
519 BMCWEB_REDFISH_SYSTEM_URI_NAME, pcieDeviceId);
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600520}
521
522inline void getPCIeDeviceProperties(
Ed Tanousac106bf2023-06-07 09:24:59 -0700523 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600524 const std::string& pcieDevicePath, const std::string& service,
525 const std::function<void(
526 const dbus::utility::DBusPropertiesMap& pcieDevProperties)>&& callback)
527{
Ed Tanousdeae6a72024-11-11 21:58:57 -0800528 dbus::utility::getAllProperties(
529 service, pcieDevicePath,
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600530 "xyz.openbmc_project.Inventory.Item.PCIeDevice",
Ed Tanousac106bf2023-06-07 09:24:59 -0700531 [asyncResp,
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600532 callback](const boost::system::error_code& ec,
533 const dbus::utility::DBusPropertiesMap& pcieDevProperties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400534 if (ec)
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600535 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400536 if (ec.value() != EBADR)
537 {
538 BMCWEB_LOG_ERROR("DBUS response error for Properties");
539 messages::internalError(asyncResp->res);
540 }
541 return;
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600542 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400543 callback(pcieDevProperties);
544 });
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600545}
546
547inline void addPCIeDeviceCommonProperties(
Ed Tanousac106bf2023-06-07 09:24:59 -0700548 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600549 const std::string& pcieDeviceId)
550{
Ed Tanousac106bf2023-06-07 09:24:59 -0700551 asyncResp->res.addHeader(
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600552 boost::beast::http::field::link,
553 "</redfish/v1/JsonSchemas/PCIeDevice/PCIeDevice.json>; rel=describedby");
Myung Bae9c75bf72023-12-10 16:38:04 -0500554 asyncResp->res.jsonValue["@odata.type"] = "#PCIeDevice.v1_19_0.PCIeDevice";
Ed Tanous253f11b2024-05-16 09:38:31 -0700555 asyncResp->res.jsonValue["@odata.id"] =
556 boost::urls::format("/redfish/v1/Systems/{}/PCIeDevices/{}",
557 BMCWEB_REDFISH_SYSTEM_URI_NAME, pcieDeviceId);
Ed Tanousac106bf2023-06-07 09:24:59 -0700558 asyncResp->res.jsonValue["Name"] = "PCIe Device";
559 asyncResp->res.jsonValue["Id"] = pcieDeviceId;
Ed Tanous539d8c62024-06-19 14:38:27 -0700560 asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
561 asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK;
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600562}
563
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500564inline void afterGetValidPcieDevicePath(
565 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
566 const std::string& pcieDeviceId, const std::string& pcieDevicePath,
567 const std::string& service)
568{
569 addPCIeDeviceCommonProperties(asyncResp, pcieDeviceId);
Myung Baef7e62c12025-09-07 14:02:08 -0500570 asset_utils::getAssetInfo(asyncResp, service, pcieDevicePath,
571 ""_json_pointer, true);
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500572 getPCIeDeviceState(asyncResp, pcieDevicePath, service);
573 getPCIeDeviceHealth(asyncResp, pcieDevicePath, service);
574 getPCIeDeviceProperties(
575 asyncResp, pcieDevicePath, service,
576 std::bind_front(addPCIeDeviceProperties, asyncResp, pcieDeviceId));
Myung Bae9c75bf72023-12-10 16:38:04 -0500577 linkAssociatedProcessor(asyncResp, pcieDevicePath);
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500578 getPCIeDeviceSlotPath(
579 pcieDevicePath, asyncResp,
580 std::bind_front(afterGetPCIeDeviceSlotPath, asyncResp));
581}
582
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400583inline void handlePCIeDeviceGet(
584 App& app, const crow::Request& req,
585 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
586 const std::string& systemName, const std::string& pcieDeviceId)
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600587{
Ed Tanousac106bf2023-06-07 09:24:59 -0700588 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600589 {
590 return;
591 }
Ed Tanous25b54db2024-04-17 15:40:31 -0700592 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanous7f3e84a2022-12-28 16:22:54 -0800593 {
594 // Option currently returns no systems. TBD
595 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
596 systemName);
597 return;
598 }
Ed Tanous253f11b2024-05-16 09:38:31 -0700599 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600600 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700601 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
602 systemName);
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600603 return;
604 }
605
606 getValidPCIeDevicePath(
Ed Tanousac106bf2023-06-07 09:24:59 -0700607 pcieDeviceId, asyncResp,
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500608 std::bind_front(afterGetValidPcieDevicePath, asyncResp, pcieDeviceId));
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600609}
610
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700611inline void requestRoutesSystemPCIeDevice(App& app)
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -0800612{
Ed Tanous22d268c2022-05-19 09:39:07 -0700613 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/PCIeDevices/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700614 .privileges(redfish::privileges::getPCIeDevice)
Ed Tanous002d39b2022-05-31 08:59:27 -0700615 .methods(boost::beast::http::verb::get)(
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600616 std::bind_front(handlePCIeDeviceGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700617}
618
Lakshmi Yadlapati35ad6132023-03-10 22:31:49 -0600619inline void addPCIeFunctionList(
620 crow::Response& res, const std::string& pcieDeviceId,
621 const dbus::utility::DBusPropertiesMap& pcieDevProperties)
622{
623 nlohmann::json& pcieFunctionList = res.jsonValue["Members"];
624 pcieFunctionList = nlohmann::json::array();
625 static constexpr const int maxPciFunctionNum = 8;
626
627 for (int functionNum = 0; functionNum < maxPciFunctionNum; functionNum++)
628 {
629 // Check if this function exists by
630 // looking for a device ID
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400631 std::string devIDProperty =
632 "Function" + std::to_string(functionNum) + "DeviceId";
Lakshmi Yadlapati35ad6132023-03-10 22:31:49 -0600633 const std::string* property = nullptr;
634 for (const auto& propEntry : pcieDevProperties)
635 {
636 if (propEntry.first == devIDProperty)
637 {
638 property = std::get_if<std::string>(&propEntry.second);
639 break;
640 }
641 }
642 if (property == nullptr || property->empty())
643 {
644 continue;
645 }
646
647 nlohmann::json::object_t pcieFunction;
Ed Tanousef4c65b2023-04-24 15:28:50 -0700648 pcieFunction["@odata.id"] = boost::urls::format(
Ed Tanous253f11b2024-05-16 09:38:31 -0700649 "/redfish/v1/Systems/{}/PCIeDevices/{}/PCIeFunctions/{}",
650 BMCWEB_REDFISH_SYSTEM_URI_NAME, pcieDeviceId,
651 std::to_string(functionNum));
Patrick Williamsb2ba3072023-05-12 10:27:39 -0500652 pcieFunctionList.emplace_back(std::move(pcieFunction));
Lakshmi Yadlapati35ad6132023-03-10 22:31:49 -0600653 }
654 res.jsonValue["PCIeFunctions@odata.count"] = pcieFunctionList.size();
655}
656
657inline void handlePCIeFunctionCollectionGet(
658 App& app, const crow::Request& req,
Ed Tanousac106bf2023-06-07 09:24:59 -0700659 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous7f3e84a2022-12-28 16:22:54 -0800660 const std::string& systemName, const std::string& pcieDeviceId)
Lakshmi Yadlapati35ad6132023-03-10 22:31:49 -0600661{
Ed Tanousac106bf2023-06-07 09:24:59 -0700662 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Lakshmi Yadlapati35ad6132023-03-10 22:31:49 -0600663 {
664 return;
665 }
Ed Tanous25b54db2024-04-17 15:40:31 -0700666 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanous7f3e84a2022-12-28 16:22:54 -0800667 {
668 // Option currently returns no systems. TBD
669 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
670 systemName);
671 return;
672 }
Lakshmi Yadlapati35ad6132023-03-10 22:31:49 -0600673
674 getValidPCIeDevicePath(
Ed Tanousac106bf2023-06-07 09:24:59 -0700675 pcieDeviceId, asyncResp,
676 [asyncResp, pcieDeviceId](const std::string& pcieDevicePath,
677 const std::string& service) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400678 asyncResp->res.addHeader(
679 boost::beast::http::field::link,
680 "</redfish/v1/JsonSchemas/PCIeFunctionCollection/PCIeFunctionCollection.json>; rel=describedby");
681 asyncResp->res.jsonValue["@odata.type"] =
682 "#PCIeFunctionCollection.PCIeFunctionCollection";
683 asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
684 "/redfish/v1/Systems/{}/PCIeDevices/{}/PCIeFunctions",
685 BMCWEB_REDFISH_SYSTEM_URI_NAME, pcieDeviceId);
686 asyncResp->res.jsonValue["Name"] = "PCIe Function Collection";
687 asyncResp->res.jsonValue["Description"] =
688 "Collection of PCIe Functions for PCIe Device " + pcieDeviceId;
689 getPCIeDeviceProperties(
690 asyncResp, pcieDevicePath, service,
691 [asyncResp, pcieDeviceId](
692 const dbus::utility::DBusPropertiesMap& pcieDevProperties) {
693 addPCIeFunctionList(asyncResp->res, pcieDeviceId,
694 pcieDevProperties);
695 });
Lakshmi Yadlapati35ad6132023-03-10 22:31:49 -0600696 });
697}
698
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700699inline void requestRoutesSystemPCIeFunctionCollection(App& app)
700{
701 /**
702 * Functions triggers appropriate requests on DBus
703 */
704 BMCWEB_ROUTE(app,
Ed Tanous7f3e84a2022-12-28 16:22:54 -0800705 "/redfish/v1/Systems/<str>/PCIeDevices/<str>/PCIeFunctions/")
Ed Tanoused398212021-06-09 17:05:54 -0700706 .privileges(redfish::privileges::getPCIeFunctionCollection)
Ed Tanous002d39b2022-05-31 08:59:27 -0700707 .methods(boost::beast::http::verb::get)(
Lakshmi Yadlapati35ad6132023-03-10 22:31:49 -0600708 std::bind_front(handlePCIeFunctionCollectionGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700709}
710
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600711inline void addPCIeFunctionProperties(
Ed Tanouse14742c2023-05-31 10:27:49 -0700712 crow::Response& resp, uint64_t pcieFunctionId,
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600713 const dbus::utility::DBusPropertiesMap& pcieDevProperties)
714{
Ed Tanouse14742c2023-05-31 10:27:49 -0700715 std::string functionName = "Function" + std::to_string(pcieFunctionId);
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600716 for (const auto& property : pcieDevProperties)
717 {
718 const std::string* strProperty =
719 std::get_if<std::string>(&property.second);
Ed Tanousdc8cfa62024-04-07 13:37:25 -0700720 if (strProperty == nullptr)
721 {
Ed Tanousdc8cfa62024-04-07 13:37:25 -0700722 continue;
723 }
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600724 if (property.first == functionName + "DeviceId")
725 {
726 resp.jsonValue["DeviceId"] = *strProperty;
727 }
728 if (property.first == functionName + "VendorId")
729 {
730 resp.jsonValue["VendorId"] = *strProperty;
731 }
732 // TODO: FunctionType and DeviceClass are Redfish enums. The D-Bus
733 // property strings should be mapped correctly to ensure these
734 // strings are Redfish enum values. For now just check for empty.
735 if (property.first == functionName + "FunctionType")
736 {
737 if (!strProperty->empty())
738 {
739 resp.jsonValue["FunctionType"] = *strProperty;
740 }
741 }
742 if (property.first == functionName + "DeviceClass")
743 {
744 if (!strProperty->empty())
745 {
746 resp.jsonValue["DeviceClass"] = *strProperty;
747 }
748 }
749 if (property.first == functionName + "ClassCode")
750 {
751 resp.jsonValue["ClassCode"] = *strProperty;
752 }
753 if (property.first == functionName + "RevisionId")
754 {
755 resp.jsonValue["RevisionId"] = *strProperty;
756 }
757 if (property.first == functionName + "SubsystemId")
758 {
759 resp.jsonValue["SubsystemId"] = *strProperty;
760 }
761 if (property.first == functionName + "SubsystemVendorId")
762 {
763 resp.jsonValue["SubsystemVendorId"] = *strProperty;
764 }
765 }
766}
767
768inline void addPCIeFunctionCommonProperties(crow::Response& resp,
769 const std::string& pcieDeviceId,
Ed Tanouse14742c2023-05-31 10:27:49 -0700770 uint64_t pcieFunctionId)
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600771{
772 resp.addHeader(
773 boost::beast::http::field::link,
774 "</redfish/v1/JsonSchemas/PCIeFunction/PCIeFunction.json>; rel=describedby");
775 resp.jsonValue["@odata.type"] = "#PCIeFunction.v1_2_3.PCIeFunction";
Ed Tanousef4c65b2023-04-24 15:28:50 -0700776 resp.jsonValue["@odata.id"] = boost::urls::format(
Ed Tanous253f11b2024-05-16 09:38:31 -0700777 "/redfish/v1/Systems/{}/PCIeDevices/{}/PCIeFunctions/{}",
778 BMCWEB_REDFISH_SYSTEM_URI_NAME, pcieDeviceId,
779 std::to_string(pcieFunctionId));
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600780 resp.jsonValue["Name"] = "PCIe Function";
Ed Tanouse14742c2023-05-31 10:27:49 -0700781 resp.jsonValue["Id"] = std::to_string(pcieFunctionId);
782 resp.jsonValue["FunctionId"] = pcieFunctionId;
Ed Tanous253f11b2024-05-16 09:38:31 -0700783 resp.jsonValue["Links"]["PCIeDevice"]["@odata.id"] =
784 boost::urls::format("/redfish/v1/Systems/{}/PCIeDevices/{}",
785 BMCWEB_REDFISH_SYSTEM_URI_NAME, pcieDeviceId);
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600786}
787
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400788inline void handlePCIeFunctionGet(
789 App& app, const crow::Request& req,
790 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
791 const std::string& systemName, const std::string& pcieDeviceId,
792 const std::string& pcieFunctionIdStr)
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600793{
Ed Tanousac106bf2023-06-07 09:24:59 -0700794 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600795 {
796 return;
797 }
Ed Tanous25b54db2024-04-17 15:40:31 -0700798 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanous7f3e84a2022-12-28 16:22:54 -0800799 {
800 // Option currently returns no systems. TBD
801 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
802 systemName);
803 return;
804 }
Ed Tanous253f11b2024-05-16 09:38:31 -0700805 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanous7f3e84a2022-12-28 16:22:54 -0800806 {
807 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
808 systemName);
809 return;
810 }
Ed Tanousdc8cfa62024-04-07 13:37:25 -0700811 std::string_view pcieFunctionIdView = pcieFunctionIdStr;
Ed Tanous7f3e84a2022-12-28 16:22:54 -0800812
Ed Tanouse14742c2023-05-31 10:27:49 -0700813 uint64_t pcieFunctionId = 0;
814 std::from_chars_result result = std::from_chars(
Ed Tanousdc8cfa62024-04-07 13:37:25 -0700815 pcieFunctionIdView.begin(), pcieFunctionIdView.end(), pcieFunctionId);
816 if (result.ec != std::errc{} || result.ptr != pcieFunctionIdView.end())
Ed Tanouse14742c2023-05-31 10:27:49 -0700817 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700818 messages::resourceNotFound(asyncResp->res, "PCIeFunction",
Ed Tanouse14742c2023-05-31 10:27:49 -0700819 pcieFunctionIdStr);
820 return;
821 }
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600822
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400823 getValidPCIeDevicePath(
824 pcieDeviceId, asyncResp,
825 [asyncResp, pcieDeviceId, pcieFunctionId](
826 const std::string& pcieDevicePath, const std::string& service) {
827 getPCIeDeviceProperties(
828 asyncResp, pcieDevicePath, service,
829 [asyncResp, pcieDeviceId, pcieFunctionId](
830 const dbus::utility::DBusPropertiesMap& pcieDevProperties) {
831 addPCIeFunctionCommonProperties(
832 asyncResp->res, pcieDeviceId, pcieFunctionId);
833 addPCIeFunctionProperties(asyncResp->res, pcieFunctionId,
834 pcieDevProperties);
835 });
Patrick Williams5a39f772023-10-20 11:20:21 -0500836 });
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600837}
838
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700839inline void requestRoutesSystemPCIeFunction(App& app)
840{
841 BMCWEB_ROUTE(
Ed Tanous7f3e84a2022-12-28 16:22:54 -0800842 app, "/redfish/v1/Systems/<str>/PCIeDevices/<str>/PCIeFunctions/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700843 .privileges(redfish::privileges::getPCIeFunction)
Ed Tanous002d39b2022-05-31 08:59:27 -0700844 .methods(boost::beast::http::verb::get)(
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600845 std::bind_front(handlePCIeFunctionGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700846}
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -0800847
848} // namespace redfish