blob: 7ddbaa0177c538244a35d5679e63b448804a2e11 [file] [log] [blame]
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -08001/*
Ed Tanous6be832e2024-09-10 11:44:48 -07002Copyright (c) 2018 Intel Corporation
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -080015*/
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
Ed Tanous4ff0f1f2024-09-04 17:27:37 -070044inline void handlePCIeDevicePath(
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -060045 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(
Konstantin Aladyshev3a58c5a2024-08-05 12:57:13 +030062 pcieDevicePath, pcieDeviceInterface,
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
Ed Tanous4ff0f1f2024-09-04 17:27:37 -070081inline void getValidPCIeDevicePath(
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -060082 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
Ed Tanous4ff0f1f2024-09-04 17:27:37 -0700105inline void handlePCIeDeviceCollectionGet(
Lakshmi Yadlapatib38fa2a2023-03-10 16:19:46 -0600106 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