blob: 97f1e245256ede9bc96494f225c6dd3116da1cf7 [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 Tanous0ec8b832022-03-14 14:56:47 -070021#include "generated/enums/pcie_device.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"
Ed Tanous0ec8b832022-03-14 14:56:47 -070026
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -080027#include <boost/system/linux_error.hpp>
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +020028#include <sdbusplus/asio/property.hpp>
29#include <sdbusplus/unpack_properties.hpp>
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -080030
31namespace redfish
32{
33
Gunnar Mills1214b7e2020-06-04 10:11:30 -050034static constexpr char const* pcieService = "xyz.openbmc_project.PCIe";
35static constexpr char const* pciePath = "/xyz/openbmc_project/PCIe";
36static constexpr char const* pcieDeviceInterface =
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -080037 "xyz.openbmc_project.PCIe.Device";
38
Ed Tanousb5a76932020-09-29 16:16:58 -070039static inline void
zhanghch058d1b46d2021-04-01 11:18:24 +080040 getPCIeDeviceList(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanousb5a76932020-09-29 16:16:58 -070041 const std::string& name)
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -080042{
George Liu7a1dbc42022-12-07 16:03:22 +080043 dbus::utility::getSubTreePaths(
44 pciePath, 1, {},
45 [asyncResp, name](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -080046 const dbus::utility::MapperGetSubTreePathsResponse&
47 pcieDevicePaths) {
Ed Tanous002d39b2022-05-31 08:59:27 -070048 if (ec)
49 {
50 BMCWEB_LOG_DEBUG << "no PCIe device paths found ec: "
51 << ec.message();
52 // Not an error, system just doesn't have PCIe info
53 return;
54 }
55 nlohmann::json& pcieDeviceList = asyncResp->res.jsonValue[name];
56 pcieDeviceList = nlohmann::json::array();
57 for (const std::string& pcieDevicePath : pcieDevicePaths)
58 {
59 size_t devStart = pcieDevicePath.rfind('/');
60 if (devStart == std::string::npos)
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -080061 {
Ed Tanous002d39b2022-05-31 08:59:27 -070062 continue;
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -080063 }
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -080064
Ed Tanous002d39b2022-05-31 08:59:27 -070065 std::string devName = pcieDevicePath.substr(devStart + 1);
66 if (devName.empty())
67 {
68 continue;
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -080069 }
Ed Tanous002d39b2022-05-31 08:59:27 -070070 nlohmann::json::object_t pcieDevice;
Willy Tueddfc432022-09-26 16:46:38 +000071 pcieDevice["@odata.id"] = crow::utility::urlFromPieces(
72 "redfish", "v1", "Systems", "system", "PCIeDevices", devName);
Ed Tanous002d39b2022-05-31 08:59:27 -070073 pcieDeviceList.push_back(std::move(pcieDevice));
74 }
75 asyncResp->res.jsonValue[name + "@odata.count"] = pcieDeviceList.size();
George Liu7a1dbc42022-12-07 16:03:22 +080076 });
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -080077}
78
Lakshmi Yadlapatib38fa2a2023-03-10 16:19:46 -060079static inline void handlePCIeDeviceCollectionGet(
80 crow::App& app, const crow::Request& req,
81 const std::shared_ptr<bmcweb::AsyncResp>& aResp,
82 const std::string& systemName)
83{
84 if (!redfish::setUpRedfishRoute(app, req, aResp))
85 {
86 return;
87 }
88 if (systemName != "system")
89 {
90 messages::resourceNotFound(aResp->res, "ComputerSystem", systemName);
91 return;
92 }
93 aResp->res.addHeader(boost::beast::http::field::link,
94 "</redfish/v1/JsonSchemas/PCIeDeviceCollection/"
95 "PCIeDeviceCollection.json>; rel=describedby");
96 aResp->res.jsonValue["@odata.type"] =
97 "#PCIeDeviceCollection.PCIeDeviceCollection";
98 aResp->res.jsonValue["@odata.id"] =
99 "/redfish/v1/Systems/system/PCIeDevices";
100 aResp->res.jsonValue["Name"] = "PCIe Device Collection";
101 aResp->res.jsonValue["Description"] = "Collection of PCIe Devices";
102 aResp->res.jsonValue["Members"] = nlohmann::json::array();
103 aResp->res.jsonValue["Members@odata.count"] = 0;
104
105 constexpr std::array<std::string_view, 1> interfaces{
106 "xyz.openbmc_project.Inventory.Item.PCIeDevice"};
107 collection_util::getCollectionMembers(
108 aResp, boost::urls::url("/redfish/v1/Systems/system/PCIeDevices"),
109 interfaces);
110}
111
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700112inline void requestRoutesSystemPCIeDeviceCollection(App& app)
Jason M. Billsadbe1922019-10-14 15:44:35 -0700113{
Jason M. Billsadbe1922019-10-14 15:44:35 -0700114 /**
115 * Functions triggers appropriate requests on DBus
116 */
Ed Tanous22d268c2022-05-19 09:39:07 -0700117 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/PCIeDevices/")
Ed Tanoused398212021-06-09 17:05:54 -0700118 .privileges(redfish::privileges::getPCIeDeviceCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700119 .methods(boost::beast::http::verb::get)(
Lakshmi Yadlapatib38fa2a2023-03-10 16:19:46 -0600120 std::bind_front(handlePCIeDeviceCollectionGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700121}
122
Ed Tanous0ec8b832022-03-14 14:56:47 -0700123inline std::optional<pcie_device::PCIeTypes>
Spencer Ku62cd45a2021-11-22 16:41:25 +0800124 redfishPcieGenerationFromDbus(const std::string& generationInUse)
125{
126 if (generationInUse ==
127 "xyz.openbmc_project.Inventory.Item.PCIeSlot.Generations.Gen1")
128 {
Ed Tanous0ec8b832022-03-14 14:56:47 -0700129 return pcie_device::PCIeTypes::Gen1;
Spencer Ku62cd45a2021-11-22 16:41:25 +0800130 }
131 if (generationInUse ==
132 "xyz.openbmc_project.Inventory.Item.PCIeSlot.Generations.Gen2")
133 {
Ed Tanous0ec8b832022-03-14 14:56:47 -0700134 return pcie_device::PCIeTypes::Gen2;
Spencer Ku62cd45a2021-11-22 16:41:25 +0800135 }
136 if (generationInUse ==
137 "xyz.openbmc_project.Inventory.Item.PCIeSlot.Generations.Gen3")
138 {
Ed Tanous0ec8b832022-03-14 14:56:47 -0700139 return pcie_device::PCIeTypes::Gen3;
Spencer Ku62cd45a2021-11-22 16:41:25 +0800140 }
141 if (generationInUse ==
142 "xyz.openbmc_project.Inventory.Item.PCIeSlot.Generations.Gen4")
143 {
Ed Tanous0ec8b832022-03-14 14:56:47 -0700144 return pcie_device::PCIeTypes::Gen4;
Spencer Ku62cd45a2021-11-22 16:41:25 +0800145 }
146 if (generationInUse ==
147 "xyz.openbmc_project.Inventory.Item.PCIeSlot.Generations.Gen5")
148 {
Ed Tanous0ec8b832022-03-14 14:56:47 -0700149 return pcie_device::PCIeTypes::Gen5;
Spencer Ku62cd45a2021-11-22 16:41:25 +0800150 }
Ed Tanouse825cbc2022-06-17 11:39:22 -0700151 if (generationInUse.empty() ||
152 generationInUse ==
153 "xyz.openbmc_project.Inventory.Item.PCIeSlot.Generations.Unknown")
Spencer Ku62cd45a2021-11-22 16:41:25 +0800154 {
Ed Tanous0ec8b832022-03-14 14:56:47 -0700155 return pcie_device::PCIeTypes::Invalid;
Spencer Ku62cd45a2021-11-22 16:41:25 +0800156 }
157
158 // The value is not unknown or Gen1-5, need return an internal error.
159 return std::nullopt;
160}
161
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700162inline void requestRoutesSystemPCIeDevice(App& app)
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -0800163{
Ed Tanous22d268c2022-05-19 09:39:07 -0700164 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/PCIeDevices/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700165 .privileges(redfish::privileges::getPCIeDevice)
Ed Tanous002d39b2022-05-31 08:59:27 -0700166 .methods(boost::beast::http::verb::get)(
167 [&app](const crow::Request& req,
168 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous22d268c2022-05-19 09:39:07 -0700169 const std::string& systemName, const std::string& device) {
Carson Labrado3ba00072022-06-06 19:40:56 +0000170 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -0700171 {
172 return;
173 }
Ed Tanous22d268c2022-05-19 09:39:07 -0700174 if (systemName != "system")
175 {
176 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
177 systemName);
178 return;
179 }
180
Ed Tanous002d39b2022-05-31 08:59:27 -0700181 auto getPCIeDeviceCallback =
182 [asyncResp, device](
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800183 const boost::system::error_code& ec,
Ed Tanous002d39b2022-05-31 08:59:27 -0700184 const dbus::utility::DBusPropertiesMap& pcieDevProperties) {
185 if (ec)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700186 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700187 BMCWEB_LOG_DEBUG
188 << "failed to get PCIe Device properties ec: " << ec.value()
189 << ": " << ec.message();
190 if (ec.value() ==
191 boost::system::linux_error::bad_request_descriptor)
192 {
193 messages::resourceNotFound(asyncResp->res, "PCIeDevice",
194 device);
195 }
196 else
197 {
198 messages::internalError(asyncResp->res);
199 }
Ed Tanous45ca1b82022-03-25 13:07:27 -0700200 return;
201 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700202
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +0200203 const std::string* manufacturer = nullptr;
204 const std::string* deviceType = nullptr;
205 const std::string* generationInUse = nullptr;
Myung Bae703f6742022-11-16 18:40:40 -0500206 const size_t* lanesInUse = nullptr;
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +0200207
208 const bool success = sdbusplus::unpackPropertiesNoThrow(
209 dbus_utils::UnpackErrorPrinter(), pcieDevProperties,
210 "Manufacturer", manufacturer, "DeviceType", deviceType,
Myung Bae703f6742022-11-16 18:40:40 -0500211 "LanesInUse", lanesInUse, "GenerationInUse", generationInUse);
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +0200212
213 if (!success)
214 {
215 messages::internalError(asyncResp->res);
216 return;
217 }
218
Myung Bae703f6742022-11-16 18:40:40 -0500219 // The default value of LanesInUse is 0, and the field will be
220 // left as off if it is a default value.
221 if (lanesInUse != nullptr && *lanesInUse != 0)
222 {
223 asyncResp->res.jsonValue["PCIeInterface"]["LanesInUse"] =
224 *lanesInUse;
225 }
226
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +0200227 if (generationInUse != nullptr)
228 {
Ed Tanous0ec8b832022-03-14 14:56:47 -0700229 std::optional<pcie_device::PCIeTypes> redfishGenerationInUse =
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +0200230 redfishPcieGenerationFromDbus(*generationInUse);
231 if (!redfishGenerationInUse)
232 {
233 messages::internalError(asyncResp->res);
234 return;
235 }
Ed Tanous0ec8b832022-03-14 14:56:47 -0700236 if (*redfishGenerationInUse != pcie_device::PCIeTypes::Invalid)
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +0200237 {
Tony Leea9f68bb2022-10-20 19:35:38 +0800238 asyncResp->res.jsonValue["PCIeInterface"]["PCIeType"] =
239 *redfishGenerationInUse;
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +0200240 }
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +0200241 }
242
243 if (manufacturer != nullptr)
244 {
245 asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
246 }
247
248 if (deviceType != nullptr)
249 {
250 asyncResp->res.jsonValue["DeviceType"] = *deviceType;
251 }
252
Ed Tanous002d39b2022-05-31 08:59:27 -0700253 asyncResp->res.jsonValue["@odata.type"] =
254 "#PCIeDevice.v1_4_0.PCIeDevice";
255 asyncResp->res.jsonValue["@odata.id"] =
Willy Tueddfc432022-09-26 16:46:38 +0000256 crow::utility::urlFromPieces("redfish", "v1", "Systems",
257 "system", "PCIeDevices", device);
Ed Tanous002d39b2022-05-31 08:59:27 -0700258 asyncResp->res.jsonValue["Name"] = "PCIe Device";
259 asyncResp->res.jsonValue["Id"] = device;
260
261 asyncResp->res.jsonValue["PCIeFunctions"]["@odata.id"] =
Willy Tueddfc432022-09-26 16:46:38 +0000262 crow::utility::urlFromPieces("redfish", "v1", "Systems",
263 "system", "PCIeDevices", device,
264 "PCIeFunctions");
Ed Tanous002d39b2022-05-31 08:59:27 -0700265 };
266 std::string escapedPath = std::string(pciePath) + "/" + device;
267 dbus::utility::escapePathForDbus(escapedPath);
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +0200268 sdbusplus::asio::getAllProperties(
269 *crow::connections::systemBus, pcieService, escapedPath,
270 pcieDeviceInterface, std::move(getPCIeDeviceCallback));
Ed Tanous45ca1b82022-03-25 13:07:27 -0700271 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700272}
273
274inline void requestRoutesSystemPCIeFunctionCollection(App& app)
275{
276 /**
277 * Functions triggers appropriate requests on DBus
278 */
279 BMCWEB_ROUTE(app,
280 "/redfish/v1/Systems/system/PCIeDevices/<str>/PCIeFunctions/")
Ed Tanoused398212021-06-09 17:05:54 -0700281 .privileges(redfish::privileges::getPCIeFunctionCollection)
Ed Tanous002d39b2022-05-31 08:59:27 -0700282 .methods(boost::beast::http::verb::get)(
283 [&app](const crow::Request& req,
284 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
285 const std::string& device) {
Carson Labrado3ba00072022-06-06 19:40:56 +0000286 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -0700287 {
288 return;
289 }
290
291 asyncResp->res.jsonValue["@odata.type"] =
292 "#PCIeFunctionCollection.PCIeFunctionCollection";
Willy Tueddfc432022-09-26 16:46:38 +0000293 asyncResp->res.jsonValue["@odata.id"] = crow::utility::urlFromPieces(
294 "redfish", "v1", "Systems", "system", "PCIeDevices", device,
295 "PCIeFunctions");
Ed Tanous002d39b2022-05-31 08:59:27 -0700296 asyncResp->res.jsonValue["Name"] = "PCIe Function Collection";
297 asyncResp->res.jsonValue["Description"] =
298 "Collection of PCIe Functions for PCIe Device " + device;
299
300 auto getPCIeDeviceCallback =
301 [asyncResp, device](
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800302 const boost::system::error_code& ec,
Ed Tanous002d39b2022-05-31 08:59:27 -0700303 const dbus::utility::DBusPropertiesMap& pcieDevProperties) {
304 if (ec)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700305 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700306 BMCWEB_LOG_DEBUG
307 << "failed to get PCIe Device properties ec: " << ec.value()
308 << ": " << ec.message();
309 if (ec.value() ==
310 boost::system::linux_error::bad_request_descriptor)
311 {
312 messages::resourceNotFound(asyncResp->res, "PCIeDevice",
313 device);
314 }
315 else
316 {
317 messages::internalError(asyncResp->res);
318 }
Ed Tanous45ca1b82022-03-25 13:07:27 -0700319 return;
320 }
Ed Tanous14766872022-03-15 10:44:42 -0700321
Ed Tanous002d39b2022-05-31 08:59:27 -0700322 nlohmann::json& pcieFunctionList =
323 asyncResp->res.jsonValue["Members"];
324 pcieFunctionList = nlohmann::json::array();
325 static constexpr const int maxPciFunctionNum = 8;
326 for (int functionNum = 0; functionNum < maxPciFunctionNum;
327 functionNum++)
328 {
329 // Check if this function exists by looking for a
330 // device ID
331 std::string devIDProperty =
332 "Function" + std::to_string(functionNum) + "DeviceId";
333 const std::string* property = nullptr;
334 for (const auto& propEntry : pcieDevProperties)
335 {
336 if (propEntry.first == devIDProperty)
Ed Tanous45ca1b82022-03-25 13:07:27 -0700337 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700338 property = std::get_if<std::string>(&propEntry.second);
Ed Tanous45ca1b82022-03-25 13:07:27 -0700339 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700340 }
Nan Zhoufb0ecc32022-10-17 19:17:36 +0000341 if (property == nullptr || property->empty())
Ed Tanous002d39b2022-05-31 08:59:27 -0700342 {
Nan Zhoue28ce0e2022-10-13 22:28:36 +0000343 continue;
Ed Tanous002d39b2022-05-31 08:59:27 -0700344 }
345 nlohmann::json::object_t pcieFunction;
Willy Tueddfc432022-09-26 16:46:38 +0000346 pcieFunction["@odata.id"] = crow::utility::urlFromPieces(
347 "redfish", "v1", "Systems", "system", "PCIeDevices", device,
348 "PCIeFunctions", std::to_string(functionNum));
Ed Tanous002d39b2022-05-31 08:59:27 -0700349 pcieFunctionList.push_back(std::move(pcieFunction));
350 }
351 asyncResp->res.jsonValue["Members@odata.count"] =
352 pcieFunctionList.size();
353 };
354 std::string escapedPath = std::string(pciePath) + "/" + device;
355 dbus::utility::escapePathForDbus(escapedPath);
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +0200356 sdbusplus::asio::getAllProperties(
357 *crow::connections::systemBus, pcieService, escapedPath,
358 pcieDeviceInterface, std::move(getPCIeDeviceCallback));
Ed Tanous45ca1b82022-03-25 13:07:27 -0700359 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700360}
361
362inline void requestRoutesSystemPCIeFunction(App& app)
363{
364 BMCWEB_ROUTE(
365 app,
366 "/redfish/v1/Systems/system/PCIeDevices/<str>/PCIeFunctions/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700367 .privileges(redfish::privileges::getPCIeFunction)
Ed Tanous002d39b2022-05-31 08:59:27 -0700368 .methods(boost::beast::http::verb::get)(
369 [&app](const crow::Request& req,
370 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
371 const std::string& device, const std::string& function) {
Carson Labrado3ba00072022-06-06 19:40:56 +0000372 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -0700373 {
374 return;
375 }
376 auto getPCIeDeviceCallback =
377 [asyncResp, device, function](
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800378 const boost::system::error_code& ec,
Ed Tanous002d39b2022-05-31 08:59:27 -0700379 const dbus::utility::DBusPropertiesMap& pcieDevProperties) {
380 if (ec)
Ed Tanous45ca1b82022-03-25 13:07:27 -0700381 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700382 BMCWEB_LOG_DEBUG
383 << "failed to get PCIe Device properties ec: " << ec.value()
384 << ": " << ec.message();
385 if (ec.value() ==
386 boost::system::linux_error::bad_request_descriptor)
387 {
388 messages::resourceNotFound(asyncResp->res, "PCIeDevice",
389 device);
390 }
391 else
392 {
393 messages::internalError(asyncResp->res);
394 }
Ed Tanous45ca1b82022-03-25 13:07:27 -0700395 return;
396 }
Ed Tanous168e20c2021-12-13 14:39:53 -0800397
Ed Tanous002d39b2022-05-31 08:59:27 -0700398 // Check if this function exists by looking for a device
399 // ID
400 std::string functionName = "Function" + function;
401 std::string devIDProperty = functionName + "DeviceId";
Ed Tanousb9d36b42022-02-26 21:42:46 -0800402
Ed Tanous002d39b2022-05-31 08:59:27 -0700403 const std::string* devIdProperty = nullptr;
404 for (const auto& property : pcieDevProperties)
405 {
406 if (property.first == devIDProperty)
407 {
408 devIdProperty = std::get_if<std::string>(&property.second);
409 continue;
410 }
411 }
Tony Lee973c1352022-11-18 13:48:27 +0800412 if (devIdProperty == nullptr || devIdProperty->empty())
Ed Tanous002d39b2022-05-31 08:59:27 -0700413 {
414 messages::resourceNotFound(asyncResp->res, "PCIeFunction",
415 function);
416 return;
417 }
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -0800418
Ed Tanous002d39b2022-05-31 08:59:27 -0700419 asyncResp->res.jsonValue["@odata.type"] =
420 "#PCIeFunction.v1_2_0.PCIeFunction";
421 asyncResp->res.jsonValue["@odata.id"] =
Willy Tueddfc432022-09-26 16:46:38 +0000422 crow::utility::urlFromPieces("redfish", "v1", "Systems",
423 "system", "PCIeDevices", device,
424 "PCIeFunctions", function);
Ed Tanous002d39b2022-05-31 08:59:27 -0700425 asyncResp->res.jsonValue["Name"] = "PCIe Function";
426 asyncResp->res.jsonValue["Id"] = function;
427 asyncResp->res.jsonValue["FunctionId"] = std::stoi(function);
428 asyncResp->res.jsonValue["Links"]["PCIeDevice"]["@odata.id"] =
Willy Tueddfc432022-09-26 16:46:38 +0000429 crow::utility::urlFromPieces("redfish", "v1", "Systems",
430 "system", "PCIeDevices", device);
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700431
Ed Tanous002d39b2022-05-31 08:59:27 -0700432 for (const auto& property : pcieDevProperties)
433 {
434 const std::string* strProperty =
435 std::get_if<std::string>(&property.second);
436 if (property.first == functionName + "DeviceId")
437 {
438 asyncResp->res.jsonValue["DeviceId"] = *strProperty;
439 }
440 if (property.first == functionName + "VendorId")
441 {
442 asyncResp->res.jsonValue["VendorId"] = *strProperty;
443 }
444 if (property.first == functionName + "FunctionType")
445 {
446 asyncResp->res.jsonValue["FunctionType"] = *strProperty;
447 }
448 if (property.first == functionName + "DeviceClass")
449 {
450 asyncResp->res.jsonValue["DeviceClass"] = *strProperty;
451 }
452 if (property.first == functionName + "ClassCode")
453 {
454 asyncResp->res.jsonValue["ClassCode"] = *strProperty;
455 }
456 if (property.first == functionName + "RevisionId")
457 {
458 asyncResp->res.jsonValue["RevisionId"] = *strProperty;
459 }
460 if (property.first == functionName + "SubsystemId")
461 {
462 asyncResp->res.jsonValue["SubsystemId"] = *strProperty;
463 }
464 if (property.first == functionName + "SubsystemVendorId")
465 {
466 asyncResp->res.jsonValue["SubsystemVendorId"] =
467 *strProperty;
468 }
469 }
470 };
471 std::string escapedPath = std::string(pciePath) + "/" + device;
472 dbus::utility::escapePathForDbus(escapedPath);
Krzysztof Grobelnyd1bde9e2022-09-07 10:40:51 +0200473 sdbusplus::asio::getAllProperties(
474 *crow::connections::systemBus, pcieService, escapedPath,
475 pcieDeviceInterface, std::move(getPCIeDeviceCallback));
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700476 });
477}
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -0800478
479} // namespace redfish