blob: 441514458d3933efc0a0deb120f1c8461ade6778 [file] [log] [blame]
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -08001/*
2// Copyright (c) 2018 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
16
17#pragma once
18
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080019#include "app.hpp"
George Liu7a1dbc42022-12-07 16:03:22 +080020#include "dbus_utility.hpp"
Ed Tanous539d8c62024-06-19 14:38:27 -070021#include "generated/enums/resource.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080022#include "query.hpp"
23#include "registries/privilege_registry.hpp"
Lakshmi Yadlapatib38fa2a2023-03-10 16:19:46 -060024#include "utils/collection.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080025#include "utils/dbus_utils.hpp"
Lakshmi Yadlapatic49c3292023-04-19 16:42:35 -050026#include "utils/pcie_util.hpp"
Ed Tanous0ec8b832022-03-14 14:56:47 -070027
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -080028#include <boost/system/linux_error.hpp>
Ed Tanousef4c65b2023-04-24 15:28:50 -070029#include <boost/url/format.hpp>
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +020030#include <sdbusplus/asio/property.hpp>
31#include <sdbusplus/unpack_properties.hpp>
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -080032
Myung Bae8c1d0542024-03-12 17:50:48 -050033#include <limits>
34
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -080035namespace redfish
36{
37
Patrick Williams89492a12023-05-10 07:51:34 -050038static constexpr const char* inventoryPath = "/xyz/openbmc_project/inventory";
Lakshmi Yadlapati94c3a102023-04-05 18:11:22 -050039static constexpr std::array<std::string_view, 1> pcieDeviceInterface = {
40 "xyz.openbmc_project.Inventory.Item.PCIeDevice"};
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -050041static constexpr std::array<std::string_view, 1> pcieSlotInterface = {
42 "xyz.openbmc_project.Inventory.Item.PCIeSlot"};
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -080043
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -060044static inline void handlePCIeDevicePath(
45 const std::string& pcieDeviceId,
Ed Tanousac106bf2023-06-07 09:24:59 -070046 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -060047 const dbus::utility::MapperGetSubTreePathsResponse& pcieDevicePaths,
48 const std::function<void(const std::string& pcieDevicePath,
49 const std::string& service)>& callback)
50
51{
52 for (const std::string& pcieDevicePath : pcieDevicePaths)
53 {
54 std::string pciecDeviceName =
55 sdbusplus::message::object_path(pcieDevicePath).filename();
56 if (pciecDeviceName.empty() || pciecDeviceName != pcieDeviceId)
57 {
58 continue;
59 }
60
61 dbus::utility::getDbusObject(
62 pcieDevicePath, {},
Ed Tanousac106bf2023-06-07 09:24:59 -070063 [pcieDevicePath, asyncResp,
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -060064 callback](const boost::system::error_code& ec,
65 const dbus::utility::MapperGetObject& object) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -040066 if (ec || object.empty())
67 {
68 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
69 messages::internalError(asyncResp->res);
70 return;
71 }
72 callback(pcieDevicePath, object.begin()->first);
73 });
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -060074 return;
75 }
76
Ed Tanous62598e32023-07-17 17:06:25 -070077 BMCWEB_LOG_WARNING("PCIe Device not found");
Ed Tanousac106bf2023-06-07 09:24:59 -070078 messages::resourceNotFound(asyncResp->res, "PCIeDevice", pcieDeviceId);
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -060079}
80
81static inline void getValidPCIeDevicePath(
82 const std::string& pcieDeviceId,
Ed Tanousac106bf2023-06-07 09:24:59 -070083 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -060084 const std::function<void(const std::string& pcieDevicePath,
85 const std::string& service)>& callback)
86{
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -060087 dbus::utility::getSubTreePaths(
Lakshmi Yadlapati94c3a102023-04-05 18:11:22 -050088 inventoryPath, 0, pcieDeviceInterface,
Ed Tanousac106bf2023-06-07 09:24:59 -070089 [pcieDeviceId, asyncResp,
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -060090 callback](const boost::system::error_code& ec,
91 const dbus::utility::MapperGetSubTreePathsResponse&
92 pcieDevicePaths) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -040093 if (ec)
94 {
95 BMCWEB_LOG_ERROR("D-Bus response error on GetSubTree {}", ec);
96 messages::internalError(asyncResp->res);
97 return;
98 }
99 handlePCIeDevicePath(pcieDeviceId, asyncResp, pcieDevicePaths,
100 callback);
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600101 return;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400102 });
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600103}
104
Lakshmi Yadlapatib38fa2a2023-03-10 16:19:46 -0600105static inline void handlePCIeDeviceCollectionGet(
106 crow::App& app, const crow::Request& req,
Ed Tanousac106bf2023-06-07 09:24:59 -0700107 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Lakshmi Yadlapatib38fa2a2023-03-10 16:19:46 -0600108 const std::string& systemName)
109{
Ed Tanousac106bf2023-06-07 09:24:59 -0700110 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Lakshmi Yadlapatib38fa2a2023-03-10 16:19:46 -0600111 {
112 return;
113 }
Ed Tanous25b54db2024-04-17 15:40:31 -0700114 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanous7f3e84a2022-12-28 16:22:54 -0800115 {
116 // Option currently returns no systems. TBD
117 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
118 systemName);
119 return;
120 }
Ed Tanous253f11b2024-05-16 09:38:31 -0700121 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Lakshmi Yadlapatib38fa2a2023-03-10 16:19:46 -0600122 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700123 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
124 systemName);
Lakshmi Yadlapatib38fa2a2023-03-10 16:19:46 -0600125 return;
126 }
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600127
Ed Tanousac106bf2023-06-07 09:24:59 -0700128 asyncResp->res.addHeader(boost::beast::http::field::link,
129 "</redfish/v1/JsonSchemas/PCIeDeviceCollection/"
130 "PCIeDeviceCollection.json>; rel=describedby");
131 asyncResp->res.jsonValue["@odata.type"] =
Lakshmi Yadlapatib38fa2a2023-03-10 16:19:46 -0600132 "#PCIeDeviceCollection.PCIeDeviceCollection";
Ed Tanous253f11b2024-05-16 09:38:31 -0700133 asyncResp->res.jsonValue["@odata.id"] = std::format(
134 "/redfish/v1/Systems/{}/PCIeDevices", BMCWEB_REDFISH_SYSTEM_URI_NAME);
Ed Tanousac106bf2023-06-07 09:24:59 -0700135 asyncResp->res.jsonValue["Name"] = "PCIe Device Collection";
136 asyncResp->res.jsonValue["Description"] = "Collection of PCIe Devices";
Lakshmi Yadlapatib38fa2a2023-03-10 16:19:46 -0600137
Lakshmi Yadlapati70c4d542023-06-08 04:37:18 -0500138 pcie_util::getPCIeDeviceList(asyncResp,
139 nlohmann::json::json_pointer("/Members"));
Lakshmi Yadlapatib38fa2a2023-03-10 16:19:46 -0600140}
141
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700142inline void requestRoutesSystemPCIeDeviceCollection(App& app)
Jason M. Billsadbe1922019-10-14 15:44:35 -0700143{
Jason M. Billsadbe1922019-10-14 15:44:35 -0700144 /**
145 * Functions triggers appropriate requests on DBus
146 */
Ed Tanous22d268c2022-05-19 09:39:07 -0700147 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/PCIeDevices/")
Ed Tanoused398212021-06-09 17:05:54 -0700148 .privileges(redfish::privileges::getPCIeDeviceCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700149 .methods(boost::beast::http::verb::get)(
Lakshmi Yadlapatib38fa2a2023-03-10 16:19:46 -0600150 std::bind_front(handlePCIeDeviceCollectionGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700151}
152
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500153inline void addPCIeSlotProperties(
154 crow::Response& res, const boost::system::error_code& ec,
155 const dbus::utility::DBusPropertiesMap& pcieSlotProperties)
156{
157 if (ec)
158 {
Ed Tanous62598e32023-07-17 17:06:25 -0700159 BMCWEB_LOG_ERROR("DBUS response error for getAllProperties{}",
160 ec.value());
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500161 messages::internalError(res);
162 return;
163 }
164 std::string generation;
165 size_t lanes = 0;
166 std::string slotType;
167
168 bool success = sdbusplus::unpackPropertiesNoThrow(
169 dbus_utils::UnpackErrorPrinter(), pcieSlotProperties, "Generation",
170 generation, "Lanes", lanes, "SlotType", slotType);
171
172 if (!success)
173 {
174 messages::internalError(res);
175 return;
176 }
177
178 std::optional<pcie_device::PCIeTypes> pcieType =
179 pcie_util::redfishPcieGenerationFromDbus(generation);
180 if (!pcieType)
181 {
Ed Tanous62598e32023-07-17 17:06:25 -0700182 BMCWEB_LOG_WARNING("Unknown PCIeType: {}", generation);
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500183 }
184 else
185 {
186 if (*pcieType == pcie_device::PCIeTypes::Invalid)
187 {
Ed Tanous62598e32023-07-17 17:06:25 -0700188 BMCWEB_LOG_ERROR("Invalid PCIeType: {}", generation);
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500189 messages::internalError(res);
190 return;
191 }
192 res.jsonValue["Slot"]["PCIeType"] = *pcieType;
193 }
194
Konstantin Aladyshev82f80322023-07-10 15:00:38 +0300195 if (lanes != 0)
196 {
197 res.jsonValue["Slot"]["Lanes"] = lanes;
198 }
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500199
200 std::optional<pcie_slots::SlotTypes> redfishSlotType =
201 pcie_util::dbusSlotTypeToRf(slotType);
202 if (!redfishSlotType)
203 {
Ed Tanous62598e32023-07-17 17:06:25 -0700204 BMCWEB_LOG_WARNING("Unknown PCIeSlot Type: {}", slotType);
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500205 }
206 else
207 {
208 if (*redfishSlotType == pcie_slots::SlotTypes::Invalid)
209 {
Ed Tanous62598e32023-07-17 17:06:25 -0700210 BMCWEB_LOG_ERROR("Invalid PCIeSlot type: {}", slotType);
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500211 messages::internalError(res);
212 return;
213 }
214 res.jsonValue["Slot"]["SlotType"] = *redfishSlotType;
215 }
216}
217
218inline void getPCIeDeviceSlotPath(
219 const std::string& pcieDevicePath,
220 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
221 std::function<void(const std::string& pcieDeviceSlot)>&& callback)
222{
223 std::string associationPath = pcieDevicePath + "/contained_by";
224 dbus::utility::getAssociatedSubTreePaths(
225 associationPath, sdbusplus::message::object_path(inventoryPath), 0,
226 pcieSlotInterface,
Ed Tanous8cb2c022024-03-27 16:31:46 -0700227 [callback = std::move(callback), asyncResp, pcieDevicePath](
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500228 const boost::system::error_code& ec,
229 const dbus::utility::MapperGetSubTreePathsResponse& endpoints) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400230 if (ec)
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500231 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400232 if (ec.value() == EBADR)
233 {
234 // Missing association is not an error
235 return;
236 }
237 BMCWEB_LOG_ERROR(
238 "DBUS response error for getAssociatedSubTreePaths {}",
239 ec.value());
240 messages::internalError(asyncResp->res);
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500241 return;
242 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400243 if (endpoints.size() > 1)
244 {
245 BMCWEB_LOG_ERROR(
246 "PCIeDevice is associated with more than one PCIeSlot: {}",
247 endpoints.size());
248 messages::internalError(asyncResp->res);
249 return;
250 }
251 if (endpoints.empty())
252 {
253 // If the device doesn't have an association, return without
254 // PCIe Slot properties
255 BMCWEB_LOG_DEBUG("PCIeDevice is not associated with PCIeSlot");
256 return;
257 }
258 callback(endpoints[0]);
259 });
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500260}
261
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400262inline void afterGetDbusObject(
263 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
264 const std::string& pcieDeviceSlot, const boost::system::error_code& ec,
265 const dbus::utility::MapperGetObject& object)
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500266{
267 if (ec || object.empty())
268 {
Ed Tanous62598e32023-07-17 17:06:25 -0700269 BMCWEB_LOG_ERROR("DBUS response error for getDbusObject {}",
270 ec.value());
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500271 messages::internalError(asyncResp->res);
272 return;
273 }
274 sdbusplus::asio::getAllProperties(
275 *crow::connections::systemBus, object.begin()->first, pcieDeviceSlot,
276 "xyz.openbmc_project.Inventory.Item.PCIeSlot",
277 [asyncResp](
278 const boost::system::error_code& ec2,
279 const dbus::utility::DBusPropertiesMap& pcieSlotProperties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400280 addPCIeSlotProperties(asyncResp->res, ec2, pcieSlotProperties);
281 });
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500282}
283
284inline void afterGetPCIeDeviceSlotPath(
285 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
286 const std::string& pcieDeviceSlot)
287{
288 dbus::utility::getDbusObject(
289 pcieDeviceSlot, pcieSlotInterface,
290 [asyncResp,
291 pcieDeviceSlot](const boost::system::error_code& ec,
292 const dbus::utility::MapperGetObject& object) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400293 afterGetDbusObject(asyncResp, pcieDeviceSlot, ec, object);
294 });
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500295}
296
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400297inline void getPCIeDeviceHealth(
298 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
299 const std::string& pcieDevicePath, const std::string& service)
Lakshmi Yadlapatie164f1b2023-04-12 17:01:34 -0500300{
301 sdbusplus::asio::getProperty<bool>(
302 *crow::connections::systemBus, service, pcieDevicePath,
303 "xyz.openbmc_project.State.Decorator.OperationalStatus", "Functional",
304 [asyncResp](const boost::system::error_code& ec, const bool value) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400305 if (ec)
Lakshmi Yadlapatie164f1b2023-04-12 17:01:34 -0500306 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400307 if (ec.value() != EBADR)
308 {
309 BMCWEB_LOG_ERROR("DBUS response error for Health {}",
310 ec.value());
311 messages::internalError(asyncResp->res);
312 }
313 return;
Lakshmi Yadlapatie164f1b2023-04-12 17:01:34 -0500314 }
Lakshmi Yadlapatie164f1b2023-04-12 17:01:34 -0500315
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400316 if (!value)
317 {
318 asyncResp->res.jsonValue["Status"]["Health"] =
319 resource::Health::Critical;
320 }
321 });
Lakshmi Yadlapatie164f1b2023-04-12 17:01:34 -0500322}
323
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400324inline void getPCIeDeviceState(
325 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
326 const std::string& pcieDevicePath, const std::string& service)
Lakshmi Yadlapatic6bb3282023-04-12 16:56:49 -0500327{
328 sdbusplus::asio::getProperty<bool>(
329 *crow::connections::systemBus, service, pcieDevicePath,
330 "xyz.openbmc_project.Inventory.Item", "Present",
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500331 [asyncResp](const boost::system::error_code& ec, bool value) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400332 if (ec)
Lakshmi Yadlapatic6bb3282023-04-12 16:56:49 -0500333 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400334 if (ec.value() != EBADR)
335 {
336 BMCWEB_LOG_ERROR("DBUS response error for State");
337 messages::internalError(asyncResp->res);
338 }
339 return;
Lakshmi Yadlapatic6bb3282023-04-12 16:56:49 -0500340 }
Lakshmi Yadlapatic6bb3282023-04-12 16:56:49 -0500341
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400342 if (!value)
343 {
344 asyncResp->res.jsonValue["Status"]["State"] =
345 resource::State::Absent;
346 }
347 });
Lakshmi Yadlapatic6bb3282023-04-12 16:56:49 -0500348}
349
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400350inline void getPCIeDeviceAsset(
351 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
352 const std::string& pcieDevicePath, const std::string& service)
SunnySrivastava1984913e7732021-01-27 06:23:24 -0600353{
354 sdbusplus::asio::getAllProperties(
355 *crow::connections::systemBus, service, pcieDevicePath,
356 "xyz.openbmc_project.Inventory.Decorator.Asset",
Ed Tanousac106bf2023-06-07 09:24:59 -0700357 [pcieDevicePath, asyncResp{asyncResp}](
358 const boost::system::error_code& ec,
359 const dbus::utility::DBusPropertiesMap& assetList) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400360 if (ec)
SunnySrivastava1984913e7732021-01-27 06:23:24 -0600361 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400362 if (ec.value() != EBADR)
363 {
364 BMCWEB_LOG_ERROR("DBUS response error for Properties{}",
365 ec.value());
366 messages::internalError(asyncResp->res);
367 }
368 return;
SunnySrivastava1984913e7732021-01-27 06:23:24 -0600369 }
SunnySrivastava1984913e7732021-01-27 06:23:24 -0600370
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400371 const std::string* manufacturer = nullptr;
372 const std::string* model = nullptr;
373 const std::string* partNumber = nullptr;
374 const std::string* serialNumber = nullptr;
375 const std::string* sparePartNumber = nullptr;
SunnySrivastava1984913e7732021-01-27 06:23:24 -0600376
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400377 const bool success = sdbusplus::unpackPropertiesNoThrow(
378 dbus_utils::UnpackErrorPrinter(), assetList, "Manufacturer",
379 manufacturer, "Model", model, "PartNumber", partNumber,
380 "SerialNumber", serialNumber, "SparePartNumber",
381 sparePartNumber);
SunnySrivastava1984913e7732021-01-27 06:23:24 -0600382
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400383 if (!success)
384 {
385 messages::internalError(asyncResp->res);
386 return;
387 }
SunnySrivastava1984913e7732021-01-27 06:23:24 -0600388
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400389 if (manufacturer != nullptr)
390 {
391 asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
392 }
393 if (model != nullptr)
394 {
395 asyncResp->res.jsonValue["Model"] = *model;
396 }
SunnySrivastava1984913e7732021-01-27 06:23:24 -0600397
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400398 if (partNumber != nullptr)
399 {
400 asyncResp->res.jsonValue["PartNumber"] = *partNumber;
401 }
SunnySrivastava1984913e7732021-01-27 06:23:24 -0600402
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400403 if (serialNumber != nullptr)
404 {
405 asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
406 }
SunnySrivastava1984913e7732021-01-27 06:23:24 -0600407
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400408 if (sparePartNumber != nullptr && !sparePartNumber->empty())
409 {
410 asyncResp->res.jsonValue["SparePartNumber"] = *sparePartNumber;
411 }
412 });
SunnySrivastava1984913e7732021-01-27 06:23:24 -0600413}
414
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600415inline void addPCIeDeviceProperties(
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500416 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
417 const std::string& pcieDeviceId,
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600418 const dbus::utility::DBusPropertiesMap& pcieDevProperties)
419{
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600420 const std::string* generationInUse = nullptr;
Konstantin Aladyshev814bf202023-07-04 16:30:10 +0300421 const std::string* generationSupported = nullptr;
Konstantin Aladyshev9bb0a7f2023-07-04 12:59:34 +0300422 const size_t* lanesInUse = nullptr;
Konstantin Aladyshev814bf202023-07-04 16:30:10 +0300423 const size_t* maxLanes = nullptr;
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600424
425 const bool success = sdbusplus::unpackPropertiesNoThrow(
Ed Tanous609ba4c2023-07-11 09:14:24 -0700426 dbus_utils::UnpackErrorPrinter(), pcieDevProperties, "GenerationInUse",
427 generationInUse, "GenerationSupported", generationSupported,
428 "LanesInUse", lanesInUse, "MaxLanes", maxLanes);
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600429
430 if (!success)
431 {
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500432 messages::internalError(asyncResp->res);
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600433 return;
434 }
435
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600436 if (generationInUse != nullptr)
437 {
438 std::optional<pcie_device::PCIeTypes> redfishGenerationInUse =
Lakshmi Yadlapatic49c3292023-04-19 16:42:35 -0500439 pcie_util::redfishPcieGenerationFromDbus(*generationInUse);
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600440
441 if (!redfishGenerationInUse)
442 {
Ed Tanous62598e32023-07-17 17:06:25 -0700443 BMCWEB_LOG_WARNING("Unknown PCIe Device Generation: {}",
444 *generationInUse);
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600445 }
Lakshmi Yadlapaticf3b4842023-06-27 02:36:53 -0500446 else
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600447 {
Lakshmi Yadlapaticf3b4842023-06-27 02:36:53 -0500448 if (*redfishGenerationInUse == pcie_device::PCIeTypes::Invalid)
449 {
Ed Tanous62598e32023-07-17 17:06:25 -0700450 BMCWEB_LOG_ERROR("Invalid PCIe Device Generation: {}",
451 *generationInUse);
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500452 messages::internalError(asyncResp->res);
Lakshmi Yadlapaticf3b4842023-06-27 02:36:53 -0500453 return;
454 }
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500455 asyncResp->res.jsonValue["PCIeInterface"]["PCIeType"] =
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600456 *redfishGenerationInUse;
457 }
458 }
459
Konstantin Aladyshev814bf202023-07-04 16:30:10 +0300460 if (generationSupported != nullptr)
461 {
462 std::optional<pcie_device::PCIeTypes> redfishGenerationSupported =
463 pcie_util::redfishPcieGenerationFromDbus(*generationSupported);
464
465 if (!redfishGenerationSupported)
466 {
Ed Tanous62598e32023-07-17 17:06:25 -0700467 BMCWEB_LOG_WARNING("Unknown PCIe Device Generation: {}",
468 *generationSupported);
Konstantin Aladyshev814bf202023-07-04 16:30:10 +0300469 }
470 else
471 {
472 if (*redfishGenerationSupported == pcie_device::PCIeTypes::Invalid)
473 {
Ed Tanous62598e32023-07-17 17:06:25 -0700474 BMCWEB_LOG_ERROR("Invalid PCIe Device Generation: {}",
475 *generationSupported);
Konstantin Aladyshev814bf202023-07-04 16:30:10 +0300476 messages::internalError(asyncResp->res);
477 return;
478 }
479 asyncResp->res.jsonValue["PCIeInterface"]["MaxPCIeType"] =
480 *redfishGenerationSupported;
481 }
482 }
483
Myung Bae8c1d0542024-03-12 17:50:48 -0500484 if (lanesInUse != nullptr)
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600485 {
Myung Bae8c1d0542024-03-12 17:50:48 -0500486 if (*lanesInUse == std::numeric_limits<size_t>::max())
487 {
488 // The default value of LanesInUse is "maxint", and the field will
489 // be null if it is a default value.
490 asyncResp->res.jsonValue["PCIeInterface"]["LanesInUse"] = nullptr;
491 }
492 else
493 {
494 asyncResp->res.jsonValue["PCIeInterface"]["LanesInUse"] =
495 *lanesInUse;
496 }
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600497 }
Konstantin Aladyshev814bf202023-07-04 16:30:10 +0300498 // The default value of MaxLanes is 0, and the field will be
499 // left as off if it is a default value.
500 if (maxLanes != nullptr && *maxLanes != 0)
501 {
502 asyncResp->res.jsonValue["PCIeInterface"]["MaxLanes"] = *maxLanes;
503 }
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600504
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500505 asyncResp->res.jsonValue["PCIeFunctions"]["@odata.id"] =
506 boost::urls::format(
Ed Tanous253f11b2024-05-16 09:38:31 -0700507 "/redfish/v1/Systems/{}/PCIeDevices/{}/PCIeFunctions",
508 BMCWEB_REDFISH_SYSTEM_URI_NAME, pcieDeviceId);
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600509}
510
511inline void getPCIeDeviceProperties(
Ed Tanousac106bf2023-06-07 09:24:59 -0700512 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600513 const std::string& pcieDevicePath, const std::string& service,
514 const std::function<void(
515 const dbus::utility::DBusPropertiesMap& pcieDevProperties)>&& callback)
516{
517 sdbusplus::asio::getAllProperties(
518 *crow::connections::systemBus, service, pcieDevicePath,
519 "xyz.openbmc_project.Inventory.Item.PCIeDevice",
Ed Tanousac106bf2023-06-07 09:24:59 -0700520 [asyncResp,
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600521 callback](const boost::system::error_code& ec,
522 const dbus::utility::DBusPropertiesMap& pcieDevProperties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400523 if (ec)
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600524 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400525 if (ec.value() != EBADR)
526 {
527 BMCWEB_LOG_ERROR("DBUS response error for Properties");
528 messages::internalError(asyncResp->res);
529 }
530 return;
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600531 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400532 callback(pcieDevProperties);
533 });
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600534}
535
536inline void addPCIeDeviceCommonProperties(
Ed Tanousac106bf2023-06-07 09:24:59 -0700537 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600538 const std::string& pcieDeviceId)
539{
Ed Tanousac106bf2023-06-07 09:24:59 -0700540 asyncResp->res.addHeader(
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600541 boost::beast::http::field::link,
542 "</redfish/v1/JsonSchemas/PCIeDevice/PCIeDevice.json>; rel=describedby");
Ed Tanousac106bf2023-06-07 09:24:59 -0700543 asyncResp->res.jsonValue["@odata.type"] = "#PCIeDevice.v1_9_0.PCIeDevice";
Ed Tanous253f11b2024-05-16 09:38:31 -0700544 asyncResp->res.jsonValue["@odata.id"] =
545 boost::urls::format("/redfish/v1/Systems/{}/PCIeDevices/{}",
546 BMCWEB_REDFISH_SYSTEM_URI_NAME, pcieDeviceId);
Ed Tanousac106bf2023-06-07 09:24:59 -0700547 asyncResp->res.jsonValue["Name"] = "PCIe Device";
548 asyncResp->res.jsonValue["Id"] = pcieDeviceId;
Ed Tanous539d8c62024-06-19 14:38:27 -0700549 asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
550 asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK;
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600551}
552
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500553inline void afterGetValidPcieDevicePath(
554 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
555 const std::string& pcieDeviceId, const std::string& pcieDevicePath,
556 const std::string& service)
557{
558 addPCIeDeviceCommonProperties(asyncResp, pcieDeviceId);
559 getPCIeDeviceAsset(asyncResp, pcieDevicePath, service);
560 getPCIeDeviceState(asyncResp, pcieDevicePath, service);
561 getPCIeDeviceHealth(asyncResp, pcieDevicePath, service);
562 getPCIeDeviceProperties(
563 asyncResp, pcieDevicePath, service,
564 std::bind_front(addPCIeDeviceProperties, asyncResp, pcieDeviceId));
565 getPCIeDeviceSlotPath(
566 pcieDevicePath, asyncResp,
567 std::bind_front(afterGetPCIeDeviceSlotPath, asyncResp));
568}
569
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400570inline void handlePCIeDeviceGet(
571 App& app, const crow::Request& req,
572 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
573 const std::string& systemName, const std::string& pcieDeviceId)
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600574{
Ed Tanousac106bf2023-06-07 09:24:59 -0700575 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600576 {
577 return;
578 }
Ed Tanous25b54db2024-04-17 15:40:31 -0700579 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanous7f3e84a2022-12-28 16:22:54 -0800580 {
581 // Option currently returns no systems. TBD
582 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
583 systemName);
584 return;
585 }
Ed Tanous253f11b2024-05-16 09:38:31 -0700586 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600587 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700588 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
589 systemName);
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600590 return;
591 }
592
593 getValidPCIeDevicePath(
Ed Tanousac106bf2023-06-07 09:24:59 -0700594 pcieDeviceId, asyncResp,
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500595 std::bind_front(afterGetValidPcieDevicePath, asyncResp, pcieDeviceId));
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600596}
597
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700598inline void requestRoutesSystemPCIeDevice(App& app)
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -0800599{
Ed Tanous22d268c2022-05-19 09:39:07 -0700600 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/PCIeDevices/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700601 .privileges(redfish::privileges::getPCIeDevice)
Ed Tanous002d39b2022-05-31 08:59:27 -0700602 .methods(boost::beast::http::verb::get)(
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600603 std::bind_front(handlePCIeDeviceGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700604}
605
Lakshmi Yadlapati35ad6132023-03-10 22:31:49 -0600606inline void addPCIeFunctionList(
607 crow::Response& res, const std::string& pcieDeviceId,
608 const dbus::utility::DBusPropertiesMap& pcieDevProperties)
609{
610 nlohmann::json& pcieFunctionList = res.jsonValue["Members"];
611 pcieFunctionList = nlohmann::json::array();
612 static constexpr const int maxPciFunctionNum = 8;
613
614 for (int functionNum = 0; functionNum < maxPciFunctionNum; functionNum++)
615 {
616 // Check if this function exists by
617 // looking for a device ID
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400618 std::string devIDProperty =
619 "Function" + std::to_string(functionNum) + "DeviceId";
Lakshmi Yadlapati35ad6132023-03-10 22:31:49 -0600620 const std::string* property = nullptr;
621 for (const auto& propEntry : pcieDevProperties)
622 {
623 if (propEntry.first == devIDProperty)
624 {
625 property = std::get_if<std::string>(&propEntry.second);
626 break;
627 }
628 }
629 if (property == nullptr || property->empty())
630 {
631 continue;
632 }
633
634 nlohmann::json::object_t pcieFunction;
Ed Tanousef4c65b2023-04-24 15:28:50 -0700635 pcieFunction["@odata.id"] = boost::urls::format(
Ed Tanous253f11b2024-05-16 09:38:31 -0700636 "/redfish/v1/Systems/{}/PCIeDevices/{}/PCIeFunctions/{}",
637 BMCWEB_REDFISH_SYSTEM_URI_NAME, pcieDeviceId,
638 std::to_string(functionNum));
Patrick Williamsb2ba3072023-05-12 10:27:39 -0500639 pcieFunctionList.emplace_back(std::move(pcieFunction));
Lakshmi Yadlapati35ad6132023-03-10 22:31:49 -0600640 }
641 res.jsonValue["PCIeFunctions@odata.count"] = pcieFunctionList.size();
642}
643
644inline void handlePCIeFunctionCollectionGet(
645 App& app, const crow::Request& req,
Ed Tanousac106bf2023-06-07 09:24:59 -0700646 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous7f3e84a2022-12-28 16:22:54 -0800647 const std::string& systemName, const std::string& pcieDeviceId)
Lakshmi Yadlapati35ad6132023-03-10 22:31:49 -0600648{
Ed Tanousac106bf2023-06-07 09:24:59 -0700649 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Lakshmi Yadlapati35ad6132023-03-10 22:31:49 -0600650 {
651 return;
652 }
Ed Tanous25b54db2024-04-17 15:40:31 -0700653 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanous7f3e84a2022-12-28 16:22:54 -0800654 {
655 // Option currently returns no systems. TBD
656 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
657 systemName);
658 return;
659 }
Lakshmi Yadlapati35ad6132023-03-10 22:31:49 -0600660
661 getValidPCIeDevicePath(
Ed Tanousac106bf2023-06-07 09:24:59 -0700662 pcieDeviceId, asyncResp,
663 [asyncResp, pcieDeviceId](const std::string& pcieDevicePath,
664 const std::string& service) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400665 asyncResp->res.addHeader(
666 boost::beast::http::field::link,
667 "</redfish/v1/JsonSchemas/PCIeFunctionCollection/PCIeFunctionCollection.json>; rel=describedby");
668 asyncResp->res.jsonValue["@odata.type"] =
669 "#PCIeFunctionCollection.PCIeFunctionCollection";
670 asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
671 "/redfish/v1/Systems/{}/PCIeDevices/{}/PCIeFunctions",
672 BMCWEB_REDFISH_SYSTEM_URI_NAME, pcieDeviceId);
673 asyncResp->res.jsonValue["Name"] = "PCIe Function Collection";
674 asyncResp->res.jsonValue["Description"] =
675 "Collection of PCIe Functions for PCIe Device " + pcieDeviceId;
676 getPCIeDeviceProperties(
677 asyncResp, pcieDevicePath, service,
678 [asyncResp, pcieDeviceId](
679 const dbus::utility::DBusPropertiesMap& pcieDevProperties) {
680 addPCIeFunctionList(asyncResp->res, pcieDeviceId,
681 pcieDevProperties);
682 });
Lakshmi Yadlapati35ad6132023-03-10 22:31:49 -0600683 });
684}
685
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700686inline void requestRoutesSystemPCIeFunctionCollection(App& app)
687{
688 /**
689 * Functions triggers appropriate requests on DBus
690 */
691 BMCWEB_ROUTE(app,
Ed Tanous7f3e84a2022-12-28 16:22:54 -0800692 "/redfish/v1/Systems/<str>/PCIeDevices/<str>/PCIeFunctions/")
Ed Tanoused398212021-06-09 17:05:54 -0700693 .privileges(redfish::privileges::getPCIeFunctionCollection)
Ed Tanous002d39b2022-05-31 08:59:27 -0700694 .methods(boost::beast::http::verb::get)(
Lakshmi Yadlapati35ad6132023-03-10 22:31:49 -0600695 std::bind_front(handlePCIeFunctionCollectionGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700696}
697
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600698inline bool validatePCIeFunctionId(
Myung Baed5e74b82023-05-31 11:28:02 -0500699 uint64_t pcieFunctionId,
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600700 const dbus::utility::DBusPropertiesMap& pcieDevProperties)
701{
Myung Baed5e74b82023-05-31 11:28:02 -0500702 std::string functionName = "Function" + std::to_string(pcieFunctionId);
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600703 std::string devIDProperty = functionName + "DeviceId";
704
705 const std::string* devIdProperty = nullptr;
706 for (const auto& property : pcieDevProperties)
707 {
708 if (property.first == devIDProperty)
709 {
710 devIdProperty = std::get_if<std::string>(&property.second);
711 break;
712 }
713 }
714 return (devIdProperty != nullptr && !devIdProperty->empty());
715}
716
717inline void addPCIeFunctionProperties(
Ed Tanouse14742c2023-05-31 10:27:49 -0700718 crow::Response& resp, uint64_t pcieFunctionId,
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600719 const dbus::utility::DBusPropertiesMap& pcieDevProperties)
720{
Ed Tanouse14742c2023-05-31 10:27:49 -0700721 std::string functionName = "Function" + std::to_string(pcieFunctionId);
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600722 for (const auto& property : pcieDevProperties)
723 {
724 const std::string* strProperty =
725 std::get_if<std::string>(&property.second);
Ed Tanousdc8cfa62024-04-07 13:37:25 -0700726 if (strProperty == nullptr)
727 {
Ed Tanousdc8cfa62024-04-07 13:37:25 -0700728 continue;
729 }
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600730 if (property.first == functionName + "DeviceId")
731 {
732 resp.jsonValue["DeviceId"] = *strProperty;
733 }
734 if (property.first == functionName + "VendorId")
735 {
736 resp.jsonValue["VendorId"] = *strProperty;
737 }
738 // TODO: FunctionType and DeviceClass are Redfish enums. The D-Bus
739 // property strings should be mapped correctly to ensure these
740 // strings are Redfish enum values. For now just check for empty.
741 if (property.first == functionName + "FunctionType")
742 {
743 if (!strProperty->empty())
744 {
745 resp.jsonValue["FunctionType"] = *strProperty;
746 }
747 }
748 if (property.first == functionName + "DeviceClass")
749 {
750 if (!strProperty->empty())
751 {
752 resp.jsonValue["DeviceClass"] = *strProperty;
753 }
754 }
755 if (property.first == functionName + "ClassCode")
756 {
757 resp.jsonValue["ClassCode"] = *strProperty;
758 }
759 if (property.first == functionName + "RevisionId")
760 {
761 resp.jsonValue["RevisionId"] = *strProperty;
762 }
763 if (property.first == functionName + "SubsystemId")
764 {
765 resp.jsonValue["SubsystemId"] = *strProperty;
766 }
767 if (property.first == functionName + "SubsystemVendorId")
768 {
769 resp.jsonValue["SubsystemVendorId"] = *strProperty;
770 }
771 }
772}
773
774inline void addPCIeFunctionCommonProperties(crow::Response& resp,
775 const std::string& pcieDeviceId,
Ed Tanouse14742c2023-05-31 10:27:49 -0700776 uint64_t pcieFunctionId)
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600777{
778 resp.addHeader(
779 boost::beast::http::field::link,
780 "</redfish/v1/JsonSchemas/PCIeFunction/PCIeFunction.json>; rel=describedby");
781 resp.jsonValue["@odata.type"] = "#PCIeFunction.v1_2_3.PCIeFunction";
Ed Tanousef4c65b2023-04-24 15:28:50 -0700782 resp.jsonValue["@odata.id"] = boost::urls::format(
Ed Tanous253f11b2024-05-16 09:38:31 -0700783 "/redfish/v1/Systems/{}/PCIeDevices/{}/PCIeFunctions/{}",
784 BMCWEB_REDFISH_SYSTEM_URI_NAME, pcieDeviceId,
785 std::to_string(pcieFunctionId));
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600786 resp.jsonValue["Name"] = "PCIe Function";
Ed Tanouse14742c2023-05-31 10:27:49 -0700787 resp.jsonValue["Id"] = std::to_string(pcieFunctionId);
788 resp.jsonValue["FunctionId"] = pcieFunctionId;
Ed Tanous253f11b2024-05-16 09:38:31 -0700789 resp.jsonValue["Links"]["PCIeDevice"]["@odata.id"] =
790 boost::urls::format("/redfish/v1/Systems/{}/PCIeDevices/{}",
791 BMCWEB_REDFISH_SYSTEM_URI_NAME, pcieDeviceId);
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600792}
793
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400794inline void handlePCIeFunctionGet(
795 App& app, const crow::Request& req,
796 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
797 const std::string& systemName, const std::string& pcieDeviceId,
798 const std::string& pcieFunctionIdStr)
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600799{
Ed Tanousac106bf2023-06-07 09:24:59 -0700800 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600801 {
802 return;
803 }
Ed Tanous25b54db2024-04-17 15:40:31 -0700804 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanous7f3e84a2022-12-28 16:22:54 -0800805 {
806 // Option currently returns no systems. TBD
807 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
808 systemName);
809 return;
810 }
Ed Tanous253f11b2024-05-16 09:38:31 -0700811 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanous7f3e84a2022-12-28 16:22:54 -0800812 {
813 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
814 systemName);
815 return;
816 }
Ed Tanousdc8cfa62024-04-07 13:37:25 -0700817 std::string_view pcieFunctionIdView = pcieFunctionIdStr;
Ed Tanous7f3e84a2022-12-28 16:22:54 -0800818
Ed Tanouse14742c2023-05-31 10:27:49 -0700819 uint64_t pcieFunctionId = 0;
820 std::from_chars_result result = std::from_chars(
Ed Tanousdc8cfa62024-04-07 13:37:25 -0700821 pcieFunctionIdView.begin(), pcieFunctionIdView.end(), pcieFunctionId);
822 if (result.ec != std::errc{} || result.ptr != pcieFunctionIdView.end())
Ed Tanouse14742c2023-05-31 10:27:49 -0700823 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700824 messages::resourceNotFound(asyncResp->res, "PCIeFunction",
Ed Tanouse14742c2023-05-31 10:27:49 -0700825 pcieFunctionIdStr);
826 return;
827 }
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600828
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400829 getValidPCIeDevicePath(
830 pcieDeviceId, asyncResp,
831 [asyncResp, pcieDeviceId, pcieFunctionId](
832 const std::string& pcieDevicePath, const std::string& service) {
833 getPCIeDeviceProperties(
834 asyncResp, pcieDevicePath, service,
835 [asyncResp, pcieDeviceId, pcieFunctionId](
836 const dbus::utility::DBusPropertiesMap& pcieDevProperties) {
837 addPCIeFunctionCommonProperties(
838 asyncResp->res, pcieDeviceId, pcieFunctionId);
839 addPCIeFunctionProperties(asyncResp->res, pcieFunctionId,
840 pcieDevProperties);
841 });
Patrick Williams5a39f772023-10-20 11:20:21 -0500842 });
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600843}
844
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700845inline void requestRoutesSystemPCIeFunction(App& app)
846{
847 BMCWEB_ROUTE(
Ed Tanous7f3e84a2022-12-28 16:22:54 -0800848 app, "/redfish/v1/Systems/<str>/PCIeDevices/<str>/PCIeFunctions/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700849 .privileges(redfish::privileges::getPCIeFunction)
Ed Tanous002d39b2022-05-31 08:59:27 -0700850 .methods(boost::beast::http::verb::get)(
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600851 std::bind_front(handlePCIeFunctionGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700852}
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -0800853
854} // namespace redfish