blob: 223522b5f063f9378b4cd9e1a0f3900ace0fb73b [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 Tanous3ccb3ad2023-01-13 17:40:03 -080021#include "query.hpp"
22#include "registries/privilege_registry.hpp"
Lakshmi Yadlapatib38fa2a2023-03-10 16:19:46 -060023#include "utils/collection.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080024#include "utils/dbus_utils.hpp"
Lakshmi Yadlapatic49c3292023-04-19 16:42:35 -050025#include "utils/pcie_util.hpp"
Ed Tanous0ec8b832022-03-14 14:56:47 -070026
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -080027#include <boost/system/linux_error.hpp>
Ed Tanousef4c65b2023-04-24 15:28:50 -070028#include <boost/url/format.hpp>
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +020029#include <sdbusplus/asio/property.hpp>
30#include <sdbusplus/unpack_properties.hpp>
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -080031
32namespace redfish
33{
34
Patrick Williams89492a12023-05-10 07:51:34 -050035static constexpr const char* inventoryPath = "/xyz/openbmc_project/inventory";
Lakshmi Yadlapati94c3a102023-04-05 18:11:22 -050036static constexpr std::array<std::string_view, 1> pcieDeviceInterface = {
37 "xyz.openbmc_project.Inventory.Item.PCIeDevice"};
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -050038static constexpr std::array<std::string_view, 1> pcieSlotInterface = {
39 "xyz.openbmc_project.Inventory.Item.PCIeSlot"};
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -080040
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -060041static inline void handlePCIeDevicePath(
42 const std::string& pcieDeviceId,
Ed Tanousac106bf2023-06-07 09:24:59 -070043 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -060044 const dbus::utility::MapperGetSubTreePathsResponse& pcieDevicePaths,
45 const std::function<void(const std::string& pcieDevicePath,
46 const std::string& service)>& callback)
47
48{
49 for (const std::string& pcieDevicePath : pcieDevicePaths)
50 {
51 std::string pciecDeviceName =
52 sdbusplus::message::object_path(pcieDevicePath).filename();
53 if (pciecDeviceName.empty() || pciecDeviceName != pcieDeviceId)
54 {
55 continue;
56 }
57
58 dbus::utility::getDbusObject(
59 pcieDevicePath, {},
Ed Tanousac106bf2023-06-07 09:24:59 -070060 [pcieDevicePath, asyncResp,
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -060061 callback](const boost::system::error_code& ec,
62 const dbus::utility::MapperGetObject& object) {
63 if (ec || object.empty())
64 {
Ed Tanous62598e32023-07-17 17:06:25 -070065 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -070066 messages::internalError(asyncResp->res);
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -060067 return;
68 }
69 callback(pcieDevicePath, object.begin()->first);
Patrick Williams5a39f772023-10-20 11:20:21 -050070 });
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -060071 return;
72 }
73
Ed Tanous62598e32023-07-17 17:06:25 -070074 BMCWEB_LOG_WARNING("PCIe Device not found");
Ed Tanousac106bf2023-06-07 09:24:59 -070075 messages::resourceNotFound(asyncResp->res, "PCIeDevice", pcieDeviceId);
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -060076}
77
78static inline void getValidPCIeDevicePath(
79 const std::string& pcieDeviceId,
Ed Tanousac106bf2023-06-07 09:24:59 -070080 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -060081 const std::function<void(const std::string& pcieDevicePath,
82 const std::string& service)>& callback)
83{
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -060084 dbus::utility::getSubTreePaths(
Lakshmi Yadlapati94c3a102023-04-05 18:11:22 -050085 inventoryPath, 0, pcieDeviceInterface,
Ed Tanousac106bf2023-06-07 09:24:59 -070086 [pcieDeviceId, asyncResp,
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -060087 callback](const boost::system::error_code& ec,
88 const dbus::utility::MapperGetSubTreePathsResponse&
89 pcieDevicePaths) {
90 if (ec)
91 {
Ed Tanous62598e32023-07-17 17:06:25 -070092 BMCWEB_LOG_ERROR("D-Bus response error on GetSubTree {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -070093 messages::internalError(asyncResp->res);
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -060094 return;
95 }
Ed Tanousac106bf2023-06-07 09:24:59 -070096 handlePCIeDevicePath(pcieDeviceId, asyncResp, pcieDevicePaths,
97 callback);
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -060098 return;
Patrick Williams5a39f772023-10-20 11:20:21 -050099 });
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600100}
101
Lakshmi Yadlapatib38fa2a2023-03-10 16:19:46 -0600102static inline void handlePCIeDeviceCollectionGet(
103 crow::App& app, const crow::Request& req,
Ed Tanousac106bf2023-06-07 09:24:59 -0700104 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Lakshmi Yadlapatib38fa2a2023-03-10 16:19:46 -0600105 const std::string& systemName)
106{
Ed Tanousac106bf2023-06-07 09:24:59 -0700107 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Lakshmi Yadlapatib38fa2a2023-03-10 16:19:46 -0600108 {
109 return;
110 }
Ed Tanous7f3e84a2022-12-28 16:22:54 -0800111 if constexpr (bmcwebEnableMultiHost)
112 {
113 // Option currently returns no systems. TBD
114 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
115 systemName);
116 return;
117 }
Lakshmi Yadlapatib38fa2a2023-03-10 16:19:46 -0600118 if (systemName != "system")
119 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700120 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
121 systemName);
Lakshmi Yadlapatib38fa2a2023-03-10 16:19:46 -0600122 return;
123 }
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600124
Ed Tanousac106bf2023-06-07 09:24:59 -0700125 asyncResp->res.addHeader(boost::beast::http::field::link,
126 "</redfish/v1/JsonSchemas/PCIeDeviceCollection/"
127 "PCIeDeviceCollection.json>; rel=describedby");
128 asyncResp->res.jsonValue["@odata.type"] =
Lakshmi Yadlapatib38fa2a2023-03-10 16:19:46 -0600129 "#PCIeDeviceCollection.PCIeDeviceCollection";
Ed Tanousac106bf2023-06-07 09:24:59 -0700130 asyncResp->res.jsonValue["@odata.id"] =
Lakshmi Yadlapatib38fa2a2023-03-10 16:19:46 -0600131 "/redfish/v1/Systems/system/PCIeDevices";
Ed Tanousac106bf2023-06-07 09:24:59 -0700132 asyncResp->res.jsonValue["Name"] = "PCIe Device Collection";
133 asyncResp->res.jsonValue["Description"] = "Collection of PCIe Devices";
Lakshmi Yadlapatib38fa2a2023-03-10 16:19:46 -0600134
Lakshmi Yadlapati70c4d542023-06-08 04:37:18 -0500135 pcie_util::getPCIeDeviceList(asyncResp,
136 nlohmann::json::json_pointer("/Members"));
Lakshmi Yadlapatib38fa2a2023-03-10 16:19:46 -0600137}
138
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700139inline void requestRoutesSystemPCIeDeviceCollection(App& app)
Jason M. Billsadbe1922019-10-14 15:44:35 -0700140{
Jason M. Billsadbe1922019-10-14 15:44:35 -0700141 /**
142 * Functions triggers appropriate requests on DBus
143 */
Ed Tanous22d268c2022-05-19 09:39:07 -0700144 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/PCIeDevices/")
Ed Tanoused398212021-06-09 17:05:54 -0700145 .privileges(redfish::privileges::getPCIeDeviceCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700146 .methods(boost::beast::http::verb::get)(
Lakshmi Yadlapatib38fa2a2023-03-10 16:19:46 -0600147 std::bind_front(handlePCIeDeviceCollectionGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700148}
149
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500150inline void addPCIeSlotProperties(
151 crow::Response& res, const boost::system::error_code& ec,
152 const dbus::utility::DBusPropertiesMap& pcieSlotProperties)
153{
154 if (ec)
155 {
Ed Tanous62598e32023-07-17 17:06:25 -0700156 BMCWEB_LOG_ERROR("DBUS response error for getAllProperties{}",
157 ec.value());
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500158 messages::internalError(res);
159 return;
160 }
161 std::string generation;
162 size_t lanes = 0;
163 std::string slotType;
164
165 bool success = sdbusplus::unpackPropertiesNoThrow(
166 dbus_utils::UnpackErrorPrinter(), pcieSlotProperties, "Generation",
167 generation, "Lanes", lanes, "SlotType", slotType);
168
169 if (!success)
170 {
171 messages::internalError(res);
172 return;
173 }
174
175 std::optional<pcie_device::PCIeTypes> pcieType =
176 pcie_util::redfishPcieGenerationFromDbus(generation);
177 if (!pcieType)
178 {
Ed Tanous62598e32023-07-17 17:06:25 -0700179 BMCWEB_LOG_WARNING("Unknown PCIeType: {}", generation);
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500180 }
181 else
182 {
183 if (*pcieType == pcie_device::PCIeTypes::Invalid)
184 {
Ed Tanous62598e32023-07-17 17:06:25 -0700185 BMCWEB_LOG_ERROR("Invalid PCIeType: {}", generation);
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500186 messages::internalError(res);
187 return;
188 }
189 res.jsonValue["Slot"]["PCIeType"] = *pcieType;
190 }
191
Konstantin Aladyshev82f80322023-07-10 15:00:38 +0300192 if (lanes != 0)
193 {
194 res.jsonValue["Slot"]["Lanes"] = lanes;
195 }
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500196
197 std::optional<pcie_slots::SlotTypes> redfishSlotType =
198 pcie_util::dbusSlotTypeToRf(slotType);
199 if (!redfishSlotType)
200 {
Ed Tanous62598e32023-07-17 17:06:25 -0700201 BMCWEB_LOG_WARNING("Unknown PCIeSlot Type: {}", slotType);
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500202 }
203 else
204 {
205 if (*redfishSlotType == pcie_slots::SlotTypes::Invalid)
206 {
Ed Tanous62598e32023-07-17 17:06:25 -0700207 BMCWEB_LOG_ERROR("Invalid PCIeSlot type: {}", slotType);
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500208 messages::internalError(res);
209 return;
210 }
211 res.jsonValue["Slot"]["SlotType"] = *redfishSlotType;
212 }
213}
214
215inline void getPCIeDeviceSlotPath(
216 const std::string& pcieDevicePath,
217 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
218 std::function<void(const std::string& pcieDeviceSlot)>&& callback)
219{
220 std::string associationPath = pcieDevicePath + "/contained_by";
221 dbus::utility::getAssociatedSubTreePaths(
222 associationPath, sdbusplus::message::object_path(inventoryPath), 0,
223 pcieSlotInterface,
Ed Tanous8cb2c022024-03-27 16:31:46 -0700224 [callback = std::move(callback), asyncResp, pcieDevicePath](
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500225 const boost::system::error_code& ec,
226 const dbus::utility::MapperGetSubTreePathsResponse& endpoints) {
227 if (ec)
228 {
229 if (ec.value() == EBADR)
230 {
231 // Missing association is not an error
232 return;
233 }
Ed Tanous62598e32023-07-17 17:06:25 -0700234 BMCWEB_LOG_ERROR(
235 "DBUS response error for getAssociatedSubTreePaths {}",
236 ec.value());
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500237 messages::internalError(asyncResp->res);
238 return;
239 }
240 if (endpoints.size() > 1)
241 {
Ed Tanous62598e32023-07-17 17:06:25 -0700242 BMCWEB_LOG_ERROR(
243 "PCIeDevice is associated with more than one PCIeSlot: {}",
244 endpoints.size());
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500245 messages::internalError(asyncResp->res);
246 return;
247 }
248 if (endpoints.empty())
249 {
250 // If the device doesn't have an association, return without PCIe
251 // Slot properties
Ed Tanous62598e32023-07-17 17:06:25 -0700252 BMCWEB_LOG_DEBUG("PCIeDevice is not associated with PCIeSlot");
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500253 return;
254 }
255 callback(endpoints[0]);
Patrick Williams5a39f772023-10-20 11:20:21 -0500256 });
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500257}
258
259inline void
260 afterGetDbusObject(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
261 const std::string& pcieDeviceSlot,
262 const boost::system::error_code& ec,
263 const dbus::utility::MapperGetObject& object)
264{
265 if (ec || object.empty())
266 {
Ed Tanous62598e32023-07-17 17:06:25 -0700267 BMCWEB_LOG_ERROR("DBUS response error for getDbusObject {}",
268 ec.value());
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500269 messages::internalError(asyncResp->res);
270 return;
271 }
272 sdbusplus::asio::getAllProperties(
273 *crow::connections::systemBus, object.begin()->first, pcieDeviceSlot,
274 "xyz.openbmc_project.Inventory.Item.PCIeSlot",
275 [asyncResp](
276 const boost::system::error_code& ec2,
277 const dbus::utility::DBusPropertiesMap& pcieSlotProperties) {
278 addPCIeSlotProperties(asyncResp->res, ec2, pcieSlotProperties);
Patrick Williams5a39f772023-10-20 11:20:21 -0500279 });
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500280}
281
282inline void afterGetPCIeDeviceSlotPath(
283 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
284 const std::string& pcieDeviceSlot)
285{
286 dbus::utility::getDbusObject(
287 pcieDeviceSlot, pcieSlotInterface,
288 [asyncResp,
289 pcieDeviceSlot](const boost::system::error_code& ec,
290 const dbus::utility::MapperGetObject& object) {
291 afterGetDbusObject(asyncResp, pcieDeviceSlot, ec, object);
Patrick Williams5a39f772023-10-20 11:20:21 -0500292 });
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500293}
294
Ed Tanousac106bf2023-06-07 09:24:59 -0700295inline void
Lakshmi Yadlapatie164f1b2023-04-12 17:01:34 -0500296 getPCIeDeviceHealth(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
297 const std::string& pcieDevicePath,
298 const std::string& service)
299{
300 sdbusplus::asio::getProperty<bool>(
301 *crow::connections::systemBus, service, pcieDevicePath,
302 "xyz.openbmc_project.State.Decorator.OperationalStatus", "Functional",
303 [asyncResp](const boost::system::error_code& ec, const bool value) {
304 if (ec)
305 {
306 if (ec.value() != EBADR)
307 {
Ed Tanous62598e32023-07-17 17:06:25 -0700308 BMCWEB_LOG_ERROR("DBUS response error for Health {}",
309 ec.value());
Lakshmi Yadlapatie164f1b2023-04-12 17:01:34 -0500310 messages::internalError(asyncResp->res);
311 }
312 return;
313 }
314
315 if (!value)
316 {
317 asyncResp->res.jsonValue["Status"]["Health"] = "Critical";
318 }
Patrick Williams5a39f772023-10-20 11:20:21 -0500319 });
Lakshmi Yadlapatie164f1b2023-04-12 17:01:34 -0500320}
321
322inline void
Ed Tanousac106bf2023-06-07 09:24:59 -0700323 getPCIeDeviceState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
324 const std::string& pcieDevicePath,
325 const std::string& service)
Lakshmi Yadlapatic6bb3282023-04-12 16:56:49 -0500326{
327 sdbusplus::asio::getProperty<bool>(
328 *crow::connections::systemBus, service, pcieDevicePath,
329 "xyz.openbmc_project.Inventory.Item", "Present",
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500330 [asyncResp](const boost::system::error_code& ec, bool value) {
Lakshmi Yadlapatic6bb3282023-04-12 16:56:49 -0500331 if (ec)
332 {
333 if (ec.value() != EBADR)
334 {
Ed Tanous62598e32023-07-17 17:06:25 -0700335 BMCWEB_LOG_ERROR("DBUS response error for State");
Ed Tanousac106bf2023-06-07 09:24:59 -0700336 messages::internalError(asyncResp->res);
Lakshmi Yadlapatic6bb3282023-04-12 16:56:49 -0500337 }
338 return;
339 }
340
341 if (!value)
342 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700343 asyncResp->res.jsonValue["Status"]["State"] = "Absent";
Lakshmi Yadlapatic6bb3282023-04-12 16:56:49 -0500344 }
Patrick Williams5a39f772023-10-20 11:20:21 -0500345 });
Lakshmi Yadlapatic6bb3282023-04-12 16:56:49 -0500346}
347
Ed Tanousac106bf2023-06-07 09:24:59 -0700348inline void
349 getPCIeDeviceAsset(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
350 const std::string& pcieDevicePath,
351 const std::string& service)
SunnySrivastava1984913e7732021-01-27 06:23:24 -0600352{
353 sdbusplus::asio::getAllProperties(
354 *crow::connections::systemBus, service, pcieDevicePath,
355 "xyz.openbmc_project.Inventory.Decorator.Asset",
Ed Tanousac106bf2023-06-07 09:24:59 -0700356 [pcieDevicePath, asyncResp{asyncResp}](
357 const boost::system::error_code& ec,
358 const dbus::utility::DBusPropertiesMap& assetList) {
SunnySrivastava1984913e7732021-01-27 06:23:24 -0600359 if (ec)
360 {
361 if (ec.value() != EBADR)
362 {
Ed Tanous62598e32023-07-17 17:06:25 -0700363 BMCWEB_LOG_ERROR("DBUS response error for Properties{}",
364 ec.value());
Ed Tanousac106bf2023-06-07 09:24:59 -0700365 messages::internalError(asyncResp->res);
SunnySrivastava1984913e7732021-01-27 06:23:24 -0600366 }
367 return;
368 }
369
370 const std::string* manufacturer = nullptr;
371 const std::string* model = nullptr;
372 const std::string* partNumber = nullptr;
373 const std::string* serialNumber = nullptr;
374 const std::string* sparePartNumber = nullptr;
375
376 const bool success = sdbusplus::unpackPropertiesNoThrow(
377 dbus_utils::UnpackErrorPrinter(), assetList, "Manufacturer",
378 manufacturer, "Model", model, "PartNumber", partNumber,
379 "SerialNumber", serialNumber, "SparePartNumber", sparePartNumber);
380
381 if (!success)
382 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700383 messages::internalError(asyncResp->res);
SunnySrivastava1984913e7732021-01-27 06:23:24 -0600384 return;
385 }
386
387 if (manufacturer != nullptr)
388 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700389 asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
SunnySrivastava1984913e7732021-01-27 06:23:24 -0600390 }
391 if (model != nullptr)
392 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700393 asyncResp->res.jsonValue["Model"] = *model;
SunnySrivastava1984913e7732021-01-27 06:23:24 -0600394 }
395
396 if (partNumber != nullptr)
397 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700398 asyncResp->res.jsonValue["PartNumber"] = *partNumber;
SunnySrivastava1984913e7732021-01-27 06:23:24 -0600399 }
400
401 if (serialNumber != nullptr)
402 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700403 asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
SunnySrivastava1984913e7732021-01-27 06:23:24 -0600404 }
405
406 if (sparePartNumber != nullptr && !sparePartNumber->empty())
407 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700408 asyncResp->res.jsonValue["SparePartNumber"] = *sparePartNumber;
SunnySrivastava1984913e7732021-01-27 06:23:24 -0600409 }
Patrick Williams5a39f772023-10-20 11:20:21 -0500410 });
SunnySrivastava1984913e7732021-01-27 06:23:24 -0600411}
412
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600413inline void addPCIeDeviceProperties(
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500414 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
415 const std::string& pcieDeviceId,
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600416 const dbus::utility::DBusPropertiesMap& pcieDevProperties)
417{
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600418 const std::string* generationInUse = nullptr;
Konstantin Aladyshev814bf202023-07-04 16:30:10 +0300419 const std::string* generationSupported = nullptr;
Konstantin Aladyshev9bb0a7f2023-07-04 12:59:34 +0300420 const size_t* lanesInUse = nullptr;
Konstantin Aladyshev814bf202023-07-04 16:30:10 +0300421 const size_t* maxLanes = nullptr;
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600422
423 const bool success = sdbusplus::unpackPropertiesNoThrow(
Ed Tanous609ba4c2023-07-11 09:14:24 -0700424 dbus_utils::UnpackErrorPrinter(), pcieDevProperties, "GenerationInUse",
425 generationInUse, "GenerationSupported", generationSupported,
426 "LanesInUse", lanesInUse, "MaxLanes", maxLanes);
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600427
428 if (!success)
429 {
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500430 messages::internalError(asyncResp->res);
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600431 return;
432 }
433
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600434 if (generationInUse != nullptr)
435 {
436 std::optional<pcie_device::PCIeTypes> redfishGenerationInUse =
Lakshmi Yadlapatic49c3292023-04-19 16:42:35 -0500437 pcie_util::redfishPcieGenerationFromDbus(*generationInUse);
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600438
439 if (!redfishGenerationInUse)
440 {
Ed Tanous62598e32023-07-17 17:06:25 -0700441 BMCWEB_LOG_WARNING("Unknown PCIe Device Generation: {}",
442 *generationInUse);
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600443 }
Lakshmi Yadlapaticf3b4842023-06-27 02:36:53 -0500444 else
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600445 {
Lakshmi Yadlapaticf3b4842023-06-27 02:36:53 -0500446 if (*redfishGenerationInUse == pcie_device::PCIeTypes::Invalid)
447 {
Ed Tanous62598e32023-07-17 17:06:25 -0700448 BMCWEB_LOG_ERROR("Invalid PCIe Device Generation: {}",
449 *generationInUse);
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500450 messages::internalError(asyncResp->res);
Lakshmi Yadlapaticf3b4842023-06-27 02:36:53 -0500451 return;
452 }
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500453 asyncResp->res.jsonValue["PCIeInterface"]["PCIeType"] =
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600454 *redfishGenerationInUse;
455 }
456 }
457
Konstantin Aladyshev814bf202023-07-04 16:30:10 +0300458 if (generationSupported != nullptr)
459 {
460 std::optional<pcie_device::PCIeTypes> redfishGenerationSupported =
461 pcie_util::redfishPcieGenerationFromDbus(*generationSupported);
462
463 if (!redfishGenerationSupported)
464 {
Ed Tanous62598e32023-07-17 17:06:25 -0700465 BMCWEB_LOG_WARNING("Unknown PCIe Device Generation: {}",
466 *generationSupported);
Konstantin Aladyshev814bf202023-07-04 16:30:10 +0300467 }
468 else
469 {
470 if (*redfishGenerationSupported == pcie_device::PCIeTypes::Invalid)
471 {
Ed Tanous62598e32023-07-17 17:06:25 -0700472 BMCWEB_LOG_ERROR("Invalid PCIe Device Generation: {}",
473 *generationSupported);
Konstantin Aladyshev814bf202023-07-04 16:30:10 +0300474 messages::internalError(asyncResp->res);
475 return;
476 }
477 asyncResp->res.jsonValue["PCIeInterface"]["MaxPCIeType"] =
478 *redfishGenerationSupported;
479 }
480 }
481
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600482 // The default value of LanesInUse is 0, and the field will be
483 // left as off if it is a default value.
484 if (lanesInUse != nullptr && *lanesInUse != 0)
485 {
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500486 asyncResp->res.jsonValue["PCIeInterface"]["LanesInUse"] = *lanesInUse;
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600487 }
Konstantin Aladyshev814bf202023-07-04 16:30:10 +0300488 // The default value of MaxLanes is 0, and the field will be
489 // left as off if it is a default value.
490 if (maxLanes != nullptr && *maxLanes != 0)
491 {
492 asyncResp->res.jsonValue["PCIeInterface"]["MaxLanes"] = *maxLanes;
493 }
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600494
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500495 asyncResp->res.jsonValue["PCIeFunctions"]["@odata.id"] =
496 boost::urls::format(
497 "/redfish/v1/Systems/system/PCIeDevices/{}/PCIeFunctions",
498 pcieDeviceId);
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600499}
500
501inline void getPCIeDeviceProperties(
Ed Tanousac106bf2023-06-07 09:24:59 -0700502 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600503 const std::string& pcieDevicePath, const std::string& service,
504 const std::function<void(
505 const dbus::utility::DBusPropertiesMap& pcieDevProperties)>&& callback)
506{
507 sdbusplus::asio::getAllProperties(
508 *crow::connections::systemBus, service, pcieDevicePath,
509 "xyz.openbmc_project.Inventory.Item.PCIeDevice",
Ed Tanousac106bf2023-06-07 09:24:59 -0700510 [asyncResp,
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600511 callback](const boost::system::error_code& ec,
512 const dbus::utility::DBusPropertiesMap& pcieDevProperties) {
513 if (ec)
514 {
515 if (ec.value() != EBADR)
516 {
Ed Tanous62598e32023-07-17 17:06:25 -0700517 BMCWEB_LOG_ERROR("DBUS response error for Properties");
Ed Tanousac106bf2023-06-07 09:24:59 -0700518 messages::internalError(asyncResp->res);
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600519 }
520 return;
521 }
522 callback(pcieDevProperties);
Patrick Williams5a39f772023-10-20 11:20:21 -0500523 });
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600524}
525
526inline void addPCIeDeviceCommonProperties(
Ed Tanousac106bf2023-06-07 09:24:59 -0700527 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600528 const std::string& pcieDeviceId)
529{
Ed Tanousac106bf2023-06-07 09:24:59 -0700530 asyncResp->res.addHeader(
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600531 boost::beast::http::field::link,
532 "</redfish/v1/JsonSchemas/PCIeDevice/PCIeDevice.json>; rel=describedby");
Ed Tanousac106bf2023-06-07 09:24:59 -0700533 asyncResp->res.jsonValue["@odata.type"] = "#PCIeDevice.v1_9_0.PCIeDevice";
534 asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
Ed Tanousef4c65b2023-04-24 15:28:50 -0700535 "/redfish/v1/Systems/system/PCIeDevices/{}", pcieDeviceId);
Ed Tanousac106bf2023-06-07 09:24:59 -0700536 asyncResp->res.jsonValue["Name"] = "PCIe Device";
537 asyncResp->res.jsonValue["Id"] = pcieDeviceId;
538 asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
Lakshmi Yadlapatie164f1b2023-04-12 17:01:34 -0500539 asyncResp->res.jsonValue["Status"]["Health"] = "OK";
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600540}
541
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500542inline void afterGetValidPcieDevicePath(
543 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
544 const std::string& pcieDeviceId, const std::string& pcieDevicePath,
545 const std::string& service)
546{
547 addPCIeDeviceCommonProperties(asyncResp, pcieDeviceId);
548 getPCIeDeviceAsset(asyncResp, pcieDevicePath, service);
549 getPCIeDeviceState(asyncResp, pcieDevicePath, service);
550 getPCIeDeviceHealth(asyncResp, pcieDevicePath, service);
551 getPCIeDeviceProperties(
552 asyncResp, pcieDevicePath, service,
553 std::bind_front(addPCIeDeviceProperties, asyncResp, pcieDeviceId));
554 getPCIeDeviceSlotPath(
555 pcieDevicePath, asyncResp,
556 std::bind_front(afterGetPCIeDeviceSlotPath, asyncResp));
557}
558
Ed Tanousac106bf2023-06-07 09:24:59 -0700559inline void
560 handlePCIeDeviceGet(App& app, const crow::Request& req,
561 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
562 const std::string& systemName,
563 const std::string& pcieDeviceId)
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600564{
Ed Tanousac106bf2023-06-07 09:24:59 -0700565 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600566 {
567 return;
568 }
Ed Tanous7f3e84a2022-12-28 16:22:54 -0800569 if constexpr (bmcwebEnableMultiHost)
570 {
571 // Option currently returns no systems. TBD
572 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
573 systemName);
574 return;
575 }
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600576 if (systemName != "system")
577 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700578 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
579 systemName);
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600580 return;
581 }
582
583 getValidPCIeDevicePath(
Ed Tanousac106bf2023-06-07 09:24:59 -0700584 pcieDeviceId, asyncResp,
Lakshmi Yadlapatia5409992023-04-20 16:53:59 -0500585 std::bind_front(afterGetValidPcieDevicePath, asyncResp, pcieDeviceId));
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600586}
587
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700588inline void requestRoutesSystemPCIeDevice(App& app)
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -0800589{
Ed Tanous22d268c2022-05-19 09:39:07 -0700590 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/PCIeDevices/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700591 .privileges(redfish::privileges::getPCIeDevice)
Ed Tanous002d39b2022-05-31 08:59:27 -0700592 .methods(boost::beast::http::verb::get)(
Lakshmi Yadlapati543f9a72023-03-10 17:06:05 -0600593 std::bind_front(handlePCIeDeviceGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700594}
595
Lakshmi Yadlapati35ad6132023-03-10 22:31:49 -0600596inline void addPCIeFunctionList(
597 crow::Response& res, const std::string& pcieDeviceId,
598 const dbus::utility::DBusPropertiesMap& pcieDevProperties)
599{
600 nlohmann::json& pcieFunctionList = res.jsonValue["Members"];
601 pcieFunctionList = nlohmann::json::array();
602 static constexpr const int maxPciFunctionNum = 8;
603
604 for (int functionNum = 0; functionNum < maxPciFunctionNum; functionNum++)
605 {
606 // Check if this function exists by
607 // looking for a device ID
Patrick Williams89492a12023-05-10 07:51:34 -0500608 std::string devIDProperty = "Function" + std::to_string(functionNum) +
609 "DeviceId";
Lakshmi Yadlapati35ad6132023-03-10 22:31:49 -0600610 const std::string* property = nullptr;
611 for (const auto& propEntry : pcieDevProperties)
612 {
613 if (propEntry.first == devIDProperty)
614 {
615 property = std::get_if<std::string>(&propEntry.second);
616 break;
617 }
618 }
619 if (property == nullptr || property->empty())
620 {
621 continue;
622 }
623
624 nlohmann::json::object_t pcieFunction;
Ed Tanousef4c65b2023-04-24 15:28:50 -0700625 pcieFunction["@odata.id"] = boost::urls::format(
626 "/redfish/v1/Systems/system/PCIeDevices/{}/PCIeFunctions/{}",
627 pcieDeviceId, std::to_string(functionNum));
Patrick Williamsb2ba3072023-05-12 10:27:39 -0500628 pcieFunctionList.emplace_back(std::move(pcieFunction));
Lakshmi Yadlapati35ad6132023-03-10 22:31:49 -0600629 }
630 res.jsonValue["PCIeFunctions@odata.count"] = pcieFunctionList.size();
631}
632
633inline void handlePCIeFunctionCollectionGet(
634 App& app, const crow::Request& req,
Ed Tanousac106bf2023-06-07 09:24:59 -0700635 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous7f3e84a2022-12-28 16:22:54 -0800636 const std::string& systemName, const std::string& pcieDeviceId)
Lakshmi Yadlapati35ad6132023-03-10 22:31:49 -0600637{
Ed Tanousac106bf2023-06-07 09:24:59 -0700638 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Lakshmi Yadlapati35ad6132023-03-10 22:31:49 -0600639 {
640 return;
641 }
Ed Tanous7f3e84a2022-12-28 16:22:54 -0800642 if constexpr (bmcwebEnableMultiHost)
643 {
644 // Option currently returns no systems. TBD
645 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
646 systemName);
647 return;
648 }
Lakshmi Yadlapati35ad6132023-03-10 22:31:49 -0600649
650 getValidPCIeDevicePath(
Ed Tanousac106bf2023-06-07 09:24:59 -0700651 pcieDeviceId, asyncResp,
652 [asyncResp, pcieDeviceId](const std::string& pcieDevicePath,
653 const std::string& service) {
654 asyncResp->res.addHeader(
Lakshmi Yadlapati35ad6132023-03-10 22:31:49 -0600655 boost::beast::http::field::link,
656 "</redfish/v1/JsonSchemas/PCIeFunctionCollection/PCIeFunctionCollection.json>; rel=describedby");
Ed Tanousac106bf2023-06-07 09:24:59 -0700657 asyncResp->res.jsonValue["@odata.type"] =
Lakshmi Yadlapati35ad6132023-03-10 22:31:49 -0600658 "#PCIeFunctionCollection.PCIeFunctionCollection";
Ed Tanousac106bf2023-06-07 09:24:59 -0700659 asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
Ed Tanousef4c65b2023-04-24 15:28:50 -0700660 "/redfish/v1/Systems/system/PCIeDevices/{}/PCIeFunctions",
661 pcieDeviceId);
Ed Tanousac106bf2023-06-07 09:24:59 -0700662 asyncResp->res.jsonValue["Name"] = "PCIe Function Collection";
663 asyncResp->res.jsonValue["Description"] =
Lakshmi Yadlapati35ad6132023-03-10 22:31:49 -0600664 "Collection of PCIe Functions for PCIe Device " + pcieDeviceId;
665 getPCIeDeviceProperties(
Ed Tanousac106bf2023-06-07 09:24:59 -0700666 asyncResp, pcieDevicePath, service,
667 [asyncResp, pcieDeviceId](
Lakshmi Yadlapati35ad6132023-03-10 22:31:49 -0600668 const dbus::utility::DBusPropertiesMap& pcieDevProperties) {
Ed Tanousac106bf2023-06-07 09:24:59 -0700669 addPCIeFunctionList(asyncResp->res, pcieDeviceId,
670 pcieDevProperties);
Lakshmi Yadlapati35ad6132023-03-10 22:31:49 -0600671 });
Patrick Williams5a39f772023-10-20 11:20:21 -0500672 });
Lakshmi Yadlapati35ad6132023-03-10 22:31:49 -0600673}
674
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700675inline void requestRoutesSystemPCIeFunctionCollection(App& app)
676{
677 /**
678 * Functions triggers appropriate requests on DBus
679 */
680 BMCWEB_ROUTE(app,
Ed Tanous7f3e84a2022-12-28 16:22:54 -0800681 "/redfish/v1/Systems/<str>/PCIeDevices/<str>/PCIeFunctions/")
Ed Tanoused398212021-06-09 17:05:54 -0700682 .privileges(redfish::privileges::getPCIeFunctionCollection)
Ed Tanous002d39b2022-05-31 08:59:27 -0700683 .methods(boost::beast::http::verb::get)(
Lakshmi Yadlapati35ad6132023-03-10 22:31:49 -0600684 std::bind_front(handlePCIeFunctionCollectionGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700685}
686
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600687inline bool validatePCIeFunctionId(
Myung Baed5e74b82023-05-31 11:28:02 -0500688 uint64_t pcieFunctionId,
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600689 const dbus::utility::DBusPropertiesMap& pcieDevProperties)
690{
Myung Baed5e74b82023-05-31 11:28:02 -0500691 std::string functionName = "Function" + std::to_string(pcieFunctionId);
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600692 std::string devIDProperty = functionName + "DeviceId";
693
694 const std::string* devIdProperty = nullptr;
695 for (const auto& property : pcieDevProperties)
696 {
697 if (property.first == devIDProperty)
698 {
699 devIdProperty = std::get_if<std::string>(&property.second);
700 break;
701 }
702 }
703 return (devIdProperty != nullptr && !devIdProperty->empty());
704}
705
706inline void addPCIeFunctionProperties(
Ed Tanouse14742c2023-05-31 10:27:49 -0700707 crow::Response& resp, uint64_t pcieFunctionId,
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600708 const dbus::utility::DBusPropertiesMap& pcieDevProperties)
709{
Ed Tanouse14742c2023-05-31 10:27:49 -0700710 std::string functionName = "Function" + std::to_string(pcieFunctionId);
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600711 for (const auto& property : pcieDevProperties)
712 {
713 const std::string* strProperty =
714 std::get_if<std::string>(&property.second);
Ed Tanousdc8cfa62024-04-07 13:37:25 -0700715 if (strProperty == nullptr)
716 {
717 BMCWEB_LOG_ERROR("Function wasn't a string?");
718 continue;
719 }
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600720 if (property.first == functionName + "DeviceId")
721 {
722 resp.jsonValue["DeviceId"] = *strProperty;
723 }
724 if (property.first == functionName + "VendorId")
725 {
726 resp.jsonValue["VendorId"] = *strProperty;
727 }
728 // TODO: FunctionType and DeviceClass are Redfish enums. The D-Bus
729 // property strings should be mapped correctly to ensure these
730 // strings are Redfish enum values. For now just check for empty.
731 if (property.first == functionName + "FunctionType")
732 {
733 if (!strProperty->empty())
734 {
735 resp.jsonValue["FunctionType"] = *strProperty;
736 }
737 }
738 if (property.first == functionName + "DeviceClass")
739 {
740 if (!strProperty->empty())
741 {
742 resp.jsonValue["DeviceClass"] = *strProperty;
743 }
744 }
745 if (property.first == functionName + "ClassCode")
746 {
747 resp.jsonValue["ClassCode"] = *strProperty;
748 }
749 if (property.first == functionName + "RevisionId")
750 {
751 resp.jsonValue["RevisionId"] = *strProperty;
752 }
753 if (property.first == functionName + "SubsystemId")
754 {
755 resp.jsonValue["SubsystemId"] = *strProperty;
756 }
757 if (property.first == functionName + "SubsystemVendorId")
758 {
759 resp.jsonValue["SubsystemVendorId"] = *strProperty;
760 }
761 }
762}
763
764inline void addPCIeFunctionCommonProperties(crow::Response& resp,
765 const std::string& pcieDeviceId,
Ed Tanouse14742c2023-05-31 10:27:49 -0700766 uint64_t pcieFunctionId)
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600767{
768 resp.addHeader(
769 boost::beast::http::field::link,
770 "</redfish/v1/JsonSchemas/PCIeFunction/PCIeFunction.json>; rel=describedby");
771 resp.jsonValue["@odata.type"] = "#PCIeFunction.v1_2_3.PCIeFunction";
Ed Tanousef4c65b2023-04-24 15:28:50 -0700772 resp.jsonValue["@odata.id"] = boost::urls::format(
773 "/redfish/v1/Systems/system/PCIeDevices/{}/PCIeFunctions/{}",
Lakshmi Yadlapati768a1432023-06-14 12:45:54 -0500774 pcieDeviceId, std::to_string(pcieFunctionId));
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600775 resp.jsonValue["Name"] = "PCIe Function";
Ed Tanouse14742c2023-05-31 10:27:49 -0700776 resp.jsonValue["Id"] = std::to_string(pcieFunctionId);
777 resp.jsonValue["FunctionId"] = pcieFunctionId;
Ed Tanousef4c65b2023-04-24 15:28:50 -0700778 resp.jsonValue["Links"]["PCIeDevice"]["@odata.id"] = boost::urls::format(
779 "/redfish/v1/Systems/system/PCIeDevices/{}", pcieDeviceId);
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600780}
781
782inline void
783 handlePCIeFunctionGet(App& app, const crow::Request& req,
Ed Tanousac106bf2023-06-07 09:24:59 -0700784 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous7f3e84a2022-12-28 16:22:54 -0800785 const std::string& systemName,
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600786 const std::string& pcieDeviceId,
Ed Tanouse14742c2023-05-31 10:27:49 -0700787 const std::string& pcieFunctionIdStr)
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600788{
Ed Tanousac106bf2023-06-07 09:24:59 -0700789 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600790 {
791 return;
792 }
Ed Tanous7f3e84a2022-12-28 16:22:54 -0800793 if constexpr (bmcwebEnableMultiHost)
794 {
795 // Option currently returns no systems. TBD
796 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
797 systemName);
798 return;
799 }
800 if (systemName != "system")
801 {
802 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
803 systemName);
804 return;
805 }
Ed Tanousdc8cfa62024-04-07 13:37:25 -0700806 std::string_view pcieFunctionIdView = pcieFunctionIdStr;
Ed Tanous7f3e84a2022-12-28 16:22:54 -0800807
Ed Tanouse14742c2023-05-31 10:27:49 -0700808 uint64_t pcieFunctionId = 0;
809 std::from_chars_result result = std::from_chars(
Ed Tanousdc8cfa62024-04-07 13:37:25 -0700810 pcieFunctionIdView.begin(), pcieFunctionIdView.end(), pcieFunctionId);
811 if (result.ec != std::errc{} || result.ptr != pcieFunctionIdView.end())
Ed Tanouse14742c2023-05-31 10:27:49 -0700812 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700813 messages::resourceNotFound(asyncResp->res, "PCIeFunction",
Ed Tanouse14742c2023-05-31 10:27:49 -0700814 pcieFunctionIdStr);
815 return;
816 }
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600817
Ed Tanousac106bf2023-06-07 09:24:59 -0700818 getValidPCIeDevicePath(pcieDeviceId, asyncResp,
819 [asyncResp, pcieDeviceId,
820 pcieFunctionId](const std::string& pcieDevicePath,
821 const std::string& service) {
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600822 getPCIeDeviceProperties(
Ed Tanousac106bf2023-06-07 09:24:59 -0700823 asyncResp, pcieDevicePath, service,
824 [asyncResp, pcieDeviceId, pcieFunctionId](
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600825 const dbus::utility::DBusPropertiesMap& pcieDevProperties) {
Ed Tanousac106bf2023-06-07 09:24:59 -0700826 addPCIeFunctionCommonProperties(asyncResp->res, pcieDeviceId,
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600827 pcieFunctionId);
Ed Tanousac106bf2023-06-07 09:24:59 -0700828 addPCIeFunctionProperties(asyncResp->res, pcieFunctionId,
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600829 pcieDevProperties);
Patrick Williams5a39f772023-10-20 11:20:21 -0500830 });
Ed Tanousac106bf2023-06-07 09:24:59 -0700831 });
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600832}
833
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700834inline void requestRoutesSystemPCIeFunction(App& app)
835{
836 BMCWEB_ROUTE(
Ed Tanous7f3e84a2022-12-28 16:22:54 -0800837 app, "/redfish/v1/Systems/<str>/PCIeDevices/<str>/PCIeFunctions/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700838 .privileges(redfish::privileges::getPCIeFunction)
Ed Tanous002d39b2022-05-31 08:59:27 -0700839 .methods(boost::beast::http::verb::get)(
Lakshmi Yadlapati727a0462023-03-10 23:49:00 -0600840 std::bind_front(handlePCIeFunctionGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700841}
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -0800842
843} // namespace redfish