xref: /openbmc/bmcweb/features/redfish/lib/pcie.hpp (revision dede6a98fc6a55da456607128acee0a0b9f591aa)
1f5c9f8bdSJason M. Bills /*
2f5c9f8bdSJason M. Bills // Copyright (c) 2018 Intel Corporation
3f5c9f8bdSJason M. Bills //
4f5c9f8bdSJason M. Bills // Licensed under the Apache License, Version 2.0 (the "License");
5f5c9f8bdSJason M. Bills // you may not use this file except in compliance with the License.
6f5c9f8bdSJason M. Bills // You may obtain a copy of the License at
7f5c9f8bdSJason M. Bills //
8f5c9f8bdSJason M. Bills //      http://www.apache.org/licenses/LICENSE-2.0
9f5c9f8bdSJason M. Bills //
10f5c9f8bdSJason M. Bills // Unless required by applicable law or agreed to in writing, software
11f5c9f8bdSJason M. Bills // distributed under the License is distributed on an "AS IS" BASIS,
12f5c9f8bdSJason M. Bills // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f5c9f8bdSJason M. Bills // See the License for the specific language governing permissions and
14f5c9f8bdSJason M. Bills // limitations under the License.
15f5c9f8bdSJason M. Bills */
16f5c9f8bdSJason M. Bills 
17f5c9f8bdSJason M. Bills #pragma once
18f5c9f8bdSJason M. Bills 
19f5c9f8bdSJason M. Bills #include "node.hpp"
20f5c9f8bdSJason M. Bills 
21f5c9f8bdSJason M. Bills #include <boost/system/linux_error.hpp>
22f5c9f8bdSJason M. Bills 
23f5c9f8bdSJason M. Bills namespace redfish
24f5c9f8bdSJason M. Bills {
25f5c9f8bdSJason M. Bills 
26f5c9f8bdSJason M. Bills static constexpr char const *pcieService = "xyz.openbmc_project.PCIe";
27f5c9f8bdSJason M. Bills static constexpr char const *pciePath = "/xyz/openbmc_project/PCIe";
28f5c9f8bdSJason M. Bills static constexpr char const *pcieDeviceInterface =
29f5c9f8bdSJason M. Bills     "xyz.openbmc_project.PCIe.Device";
30f5c9f8bdSJason M. Bills 
31f5c9f8bdSJason M. Bills static inline void getPCIeDeviceList(std::shared_ptr<AsyncResp> asyncResp)
32f5c9f8bdSJason M. Bills {
33f5c9f8bdSJason M. Bills     auto getPCIeMapCallback =
34f5c9f8bdSJason M. Bills         [asyncResp](const boost::system::error_code ec,
35f5c9f8bdSJason M. Bills                     std::vector<std::string> &pcieDevicePaths) {
36f5c9f8bdSJason M. Bills             if (ec)
37f5c9f8bdSJason M. Bills             {
38a2730f01SAndrew Geissler                 BMCWEB_LOG_DEBUG << "no PCIe device paths found ec: "
39f5c9f8bdSJason M. Bills                                  << ec.message();
40a2730f01SAndrew Geissler                 // Not an error, system just doesn't have PCIe info
41f5c9f8bdSJason M. Bills                 return;
42f5c9f8bdSJason M. Bills             }
43f5c9f8bdSJason M. Bills             nlohmann::json &pcieDeviceList =
44f5c9f8bdSJason M. Bills                 asyncResp->res.jsonValue["PCIeDevices"];
45f5c9f8bdSJason M. Bills             pcieDeviceList = nlohmann::json::array();
46f5c9f8bdSJason M. Bills             for (const std::string &pcieDevicePath : pcieDevicePaths)
47f5c9f8bdSJason M. Bills             {
48f5c9f8bdSJason M. Bills                 size_t devStart = pcieDevicePath.rfind("/");
49f5c9f8bdSJason M. Bills                 if (devStart == std::string::npos)
50f5c9f8bdSJason M. Bills                 {
51f5c9f8bdSJason M. Bills                     continue;
52f5c9f8bdSJason M. Bills                 }
53f5c9f8bdSJason M. Bills 
54f5c9f8bdSJason M. Bills                 std::string devName = pcieDevicePath.substr(devStart + 1);
55f5c9f8bdSJason M. Bills                 if (devName.empty())
56f5c9f8bdSJason M. Bills                 {
57f5c9f8bdSJason M. Bills                     continue;
58f5c9f8bdSJason M. Bills                 }
59f5c9f8bdSJason M. Bills                 pcieDeviceList.push_back(
60f5c9f8bdSJason M. Bills                     {{"@odata.id",
61f5c9f8bdSJason M. Bills                       "/redfish/v1/Systems/system/PCIeDevices/" + devName}});
62f5c9f8bdSJason M. Bills             }
63f5c9f8bdSJason M. Bills             asyncResp->res.jsonValue["PCIeDevices@odata.count"] =
64f5c9f8bdSJason M. Bills                 pcieDeviceList.size();
65f5c9f8bdSJason M. Bills         };
66f5c9f8bdSJason M. Bills     crow::connections::systemBus->async_method_call(
67f5c9f8bdSJason M. Bills         std::move(getPCIeMapCallback), "xyz.openbmc_project.ObjectMapper",
68f5c9f8bdSJason M. Bills         "/xyz/openbmc_project/object_mapper",
69f5c9f8bdSJason M. Bills         "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
70f5c9f8bdSJason M. Bills         std::string(pciePath) + "/", 1, std::array<std::string, 0>());
71f5c9f8bdSJason M. Bills }
72f5c9f8bdSJason M. Bills 
73f5c9f8bdSJason M. Bills class SystemPCIeDevice : public Node
74f5c9f8bdSJason M. Bills {
75f5c9f8bdSJason M. Bills   public:
76f5c9f8bdSJason M. Bills     SystemPCIeDevice(CrowApp &app) :
77f5c9f8bdSJason M. Bills         Node(app, "/redfish/v1/Systems/system/PCIeDevices/<str>/",
78f5c9f8bdSJason M. Bills              std::string())
79f5c9f8bdSJason M. Bills     {
80f5c9f8bdSJason M. Bills         entityPrivileges = {
81f5c9f8bdSJason M. Bills             {boost::beast::http::verb::get, {{"Login"}}},
82f5c9f8bdSJason M. Bills             {boost::beast::http::verb::head, {{"Login"}}},
83f5c9f8bdSJason M. Bills             {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
84f5c9f8bdSJason M. Bills             {boost::beast::http::verb::put, {{"ConfigureManager"}}},
85f5c9f8bdSJason M. Bills             {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
86f5c9f8bdSJason M. Bills             {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
87f5c9f8bdSJason M. Bills     }
88f5c9f8bdSJason M. Bills 
89f5c9f8bdSJason M. Bills   private:
90f5c9f8bdSJason M. Bills     void doGet(crow::Response &res, const crow::Request &req,
91f5c9f8bdSJason M. Bills                const std::vector<std::string> &params) override
92f5c9f8bdSJason M. Bills     {
93f5c9f8bdSJason M. Bills         std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
94f5c9f8bdSJason M. Bills         if (params.size() != 1)
95f5c9f8bdSJason M. Bills         {
96f5c9f8bdSJason M. Bills             messages::internalError(asyncResp->res);
97f5c9f8bdSJason M. Bills             return;
98f5c9f8bdSJason M. Bills         }
99f5c9f8bdSJason M. Bills         const std::string &device = params[0];
100f5c9f8bdSJason M. Bills 
101f5c9f8bdSJason M. Bills         auto getPCIeDeviceCallback =
102f5c9f8bdSJason M. Bills             [asyncResp,
103f5c9f8bdSJason M. Bills              device](const boost::system::error_code ec,
104f5c9f8bdSJason M. Bills                      boost::container::flat_map<
105f5c9f8bdSJason M. Bills                          std::string, sdbusplus::message::variant<std::string>>
106f5c9f8bdSJason M. Bills                          &pcieDevProperties) {
107f5c9f8bdSJason M. Bills                 if (ec)
108f5c9f8bdSJason M. Bills                 {
109f5c9f8bdSJason M. Bills                     BMCWEB_LOG_DEBUG
110f5c9f8bdSJason M. Bills                         << "failed to get PCIe Device properties ec: "
111271584abSEd Tanous                         << ec.value() << ": " << ec.message();
112f5c9f8bdSJason M. Bills                     if (ec.value() ==
113f5c9f8bdSJason M. Bills                         boost::system::linux_error::bad_request_descriptor)
114f5c9f8bdSJason M. Bills                     {
115f5c9f8bdSJason M. Bills                         messages::resourceNotFound(asyncResp->res, "PCIeDevice",
116f5c9f8bdSJason M. Bills                                                    device);
117f5c9f8bdSJason M. Bills                     }
118f5c9f8bdSJason M. Bills                     else
119f5c9f8bdSJason M. Bills                     {
120f5c9f8bdSJason M. Bills                         messages::internalError(asyncResp->res);
121f5c9f8bdSJason M. Bills                     }
122f5c9f8bdSJason M. Bills                     return;
123f5c9f8bdSJason M. Bills                 }
124f5c9f8bdSJason M. Bills 
125f5c9f8bdSJason M. Bills                 asyncResp->res.jsonValue = {
126*dede6a98SJason M. Bills                     {"@odata.type", "#PCIeDevice.v1_4_0.PCIeDevice"},
127f5c9f8bdSJason M. Bills                     {"@odata.context",
128*dede6a98SJason M. Bills                      "/redfish/v1/$metadata#PCIeDevice.v1_4_0.PCIeDevice"},
129f5c9f8bdSJason M. Bills                     {"@odata.id",
130f5c9f8bdSJason M. Bills                      "/redfish/v1/Systems/system/PCIeDevices/" + device},
131f5c9f8bdSJason M. Bills                     {"Name", "PCIe Device"},
132f5c9f8bdSJason M. Bills                     {"Id", device}};
133f5c9f8bdSJason M. Bills 
134f5c9f8bdSJason M. Bills                 if (std::string *property =
135f5c9f8bdSJason M. Bills                         sdbusplus::message::variant_ns::get_if<std::string>(
136f5c9f8bdSJason M. Bills                             &pcieDevProperties["Manufacturer"]);
137f5c9f8bdSJason M. Bills                     property)
138f5c9f8bdSJason M. Bills                 {
139f5c9f8bdSJason M. Bills                     asyncResp->res.jsonValue["Manufacturer"] = *property;
140f5c9f8bdSJason M. Bills                 }
141f5c9f8bdSJason M. Bills 
142f5c9f8bdSJason M. Bills                 if (std::string *property =
143f5c9f8bdSJason M. Bills                         sdbusplus::message::variant_ns::get_if<std::string>(
144f5c9f8bdSJason M. Bills                             &pcieDevProperties["DeviceType"]);
145f5c9f8bdSJason M. Bills                     property)
146f5c9f8bdSJason M. Bills                 {
147f5c9f8bdSJason M. Bills                     asyncResp->res.jsonValue["DeviceType"] = *property;
148f5c9f8bdSJason M. Bills                 }
149f5c9f8bdSJason M. Bills 
150*dede6a98SJason M. Bills                 asyncResp->res.jsonValue["PCIeFunctions"] = {
151*dede6a98SJason M. Bills                     {"@odata.id", "/redfish/v1/Systems/system/PCIeDevices/" +
152*dede6a98SJason M. Bills                                       device + "/PCIeFunctions"}};
153*dede6a98SJason M. Bills             };
154*dede6a98SJason M. Bills         std::string escapedPath = std::string(pciePath) + "/" + device;
155*dede6a98SJason M. Bills         dbus::utility::escapePathForDbus(escapedPath);
156*dede6a98SJason M. Bills         crow::connections::systemBus->async_method_call(
157*dede6a98SJason M. Bills             std::move(getPCIeDeviceCallback), pcieService, escapedPath,
158*dede6a98SJason M. Bills             "org.freedesktop.DBus.Properties", "GetAll", pcieDeviceInterface);
159*dede6a98SJason M. Bills     }
160*dede6a98SJason M. Bills };
161*dede6a98SJason M. Bills 
162*dede6a98SJason M. Bills class SystemPCIeFunctionCollection : public Node
163*dede6a98SJason M. Bills {
164*dede6a98SJason M. Bills   public:
165*dede6a98SJason M. Bills     template <typename CrowApp>
166*dede6a98SJason M. Bills     SystemPCIeFunctionCollection(CrowApp &app) :
167*dede6a98SJason M. Bills         Node(app, "/redfish/v1/Systems/system/PCIeDevices/<str>/PCIeFunctions/",
168*dede6a98SJason M. Bills              std::string())
169*dede6a98SJason M. Bills     {
170*dede6a98SJason M. Bills         entityPrivileges = {
171*dede6a98SJason M. Bills             {boost::beast::http::verb::get, {{"Login"}}},
172*dede6a98SJason M. Bills             {boost::beast::http::verb::head, {{"Login"}}},
173*dede6a98SJason M. Bills             {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
174*dede6a98SJason M. Bills             {boost::beast::http::verb::put, {{"ConfigureManager"}}},
175*dede6a98SJason M. Bills             {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
176*dede6a98SJason M. Bills             {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
177*dede6a98SJason M. Bills     }
178*dede6a98SJason M. Bills 
179*dede6a98SJason M. Bills   private:
180*dede6a98SJason M. Bills     /**
181*dede6a98SJason M. Bills      * Functions triggers appropriate requests on DBus
182*dede6a98SJason M. Bills      */
183*dede6a98SJason M. Bills     void doGet(crow::Response &res, const crow::Request &req,
184*dede6a98SJason M. Bills                const std::vector<std::string> &params) override
185*dede6a98SJason M. Bills     {
186*dede6a98SJason M. Bills         std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
187*dede6a98SJason M. Bills         if (params.size() != 1)
188*dede6a98SJason M. Bills         {
189*dede6a98SJason M. Bills             messages::internalError(asyncResp->res);
190*dede6a98SJason M. Bills             return;
191*dede6a98SJason M. Bills         }
192*dede6a98SJason M. Bills         const std::string &device = params[0];
193*dede6a98SJason M. Bills         asyncResp->res.jsonValue = {
194*dede6a98SJason M. Bills             {"@odata.type", "#PCIeFunctionCollection.PCIeFunctionCollection"},
195*dede6a98SJason M. Bills             {"@odata.context",
196*dede6a98SJason M. Bills              "/redfish/v1/"
197*dede6a98SJason M. Bills              "$metadata#PCIeFunctionCollection.PCIeFunctionCollection"},
198*dede6a98SJason M. Bills             {"@odata.id", "/redfish/v1/Systems/system/PCIeDevices/" + device +
199*dede6a98SJason M. Bills                               "/PCIeFunctions"},
200*dede6a98SJason M. Bills             {"Name", "PCIe Function Collection"},
201*dede6a98SJason M. Bills             {"Description",
202*dede6a98SJason M. Bills              "Collection of PCIe Functions for PCIe Device " + device}};
203*dede6a98SJason M. Bills 
204*dede6a98SJason M. Bills         auto getPCIeDeviceCallback =
205*dede6a98SJason M. Bills             [asyncResp,
206*dede6a98SJason M. Bills              device](const boost::system::error_code ec,
207*dede6a98SJason M. Bills                      boost::container::flat_map<
208*dede6a98SJason M. Bills                          std::string, sdbusplus::message::variant<std::string>>
209*dede6a98SJason M. Bills                          &pcieDevProperties) {
210*dede6a98SJason M. Bills                 if (ec)
211*dede6a98SJason M. Bills                 {
212*dede6a98SJason M. Bills                     BMCWEB_LOG_DEBUG
213*dede6a98SJason M. Bills                         << "failed to get PCIe Device properties ec: "
214*dede6a98SJason M. Bills                         << ec.value() << ": " << ec.message();
215*dede6a98SJason M. Bills                     if (ec.value() ==
216*dede6a98SJason M. Bills                         boost::system::linux_error::bad_request_descriptor)
217*dede6a98SJason M. Bills                     {
218*dede6a98SJason M. Bills                         messages::resourceNotFound(asyncResp->res, "PCIeDevice",
219*dede6a98SJason M. Bills                                                    device);
220*dede6a98SJason M. Bills                     }
221*dede6a98SJason M. Bills                     else
222*dede6a98SJason M. Bills                     {
223*dede6a98SJason M. Bills                         messages::internalError(asyncResp->res);
224*dede6a98SJason M. Bills                     }
225*dede6a98SJason M. Bills                     return;
226*dede6a98SJason M. Bills                 }
227*dede6a98SJason M. Bills 
228f5c9f8bdSJason M. Bills                 nlohmann::json &pcieFunctionList =
229*dede6a98SJason M. Bills                     asyncResp->res.jsonValue["Members"];
230f5c9f8bdSJason M. Bills                 pcieFunctionList = nlohmann::json::array();
231f5c9f8bdSJason M. Bills                 static constexpr const int maxPciFunctionNum = 8;
232f5c9f8bdSJason M. Bills                 for (int functionNum = 0; functionNum < maxPciFunctionNum;
233f5c9f8bdSJason M. Bills                      functionNum++)
234f5c9f8bdSJason M. Bills                 {
235f5c9f8bdSJason M. Bills                     // Check if this function exists by looking for a device ID
236f5c9f8bdSJason M. Bills                     std::string devIDProperty =
237f5c9f8bdSJason M. Bills                         "Function" + std::to_string(functionNum) + "DeviceId";
238*dede6a98SJason M. Bills                     std::string *property =
239f5c9f8bdSJason M. Bills                         sdbusplus::message::variant_ns::get_if<std::string>(
240f5c9f8bdSJason M. Bills                             &pcieDevProperties[devIDProperty]);
241*dede6a98SJason M. Bills                     if (property && !property->empty())
242f5c9f8bdSJason M. Bills                     {
243f5c9f8bdSJason M. Bills                         pcieFunctionList.push_back(
244f5c9f8bdSJason M. Bills                             {{"@odata.id",
245f5c9f8bdSJason M. Bills                               "/redfish/v1/Systems/system/PCIeDevices/" +
246f5c9f8bdSJason M. Bills                                   device + "/PCIeFunctions/" +
247f5c9f8bdSJason M. Bills                                   std::to_string(functionNum)}});
248f5c9f8bdSJason M. Bills                     }
249f5c9f8bdSJason M. Bills                 }
250*dede6a98SJason M. Bills                 asyncResp->res.jsonValue["PCIeFunctions@odata.count"] =
251f5c9f8bdSJason M. Bills                     pcieFunctionList.size();
252f5c9f8bdSJason M. Bills             };
253f5c9f8bdSJason M. Bills         std::string escapedPath = std::string(pciePath) + "/" + device;
254f5c9f8bdSJason M. Bills         dbus::utility::escapePathForDbus(escapedPath);
255f5c9f8bdSJason M. Bills         crow::connections::systemBus->async_method_call(
256f5c9f8bdSJason M. Bills             std::move(getPCIeDeviceCallback), pcieService, escapedPath,
257f5c9f8bdSJason M. Bills             "org.freedesktop.DBus.Properties", "GetAll", pcieDeviceInterface);
258f5c9f8bdSJason M. Bills     }
259f5c9f8bdSJason M. Bills };
260f5c9f8bdSJason M. Bills 
261f5c9f8bdSJason M. Bills class SystemPCIeFunction : public Node
262f5c9f8bdSJason M. Bills {
263f5c9f8bdSJason M. Bills   public:
264f5c9f8bdSJason M. Bills     SystemPCIeFunction(CrowApp &app) :
265f5c9f8bdSJason M. Bills         Node(
266f5c9f8bdSJason M. Bills             app,
267f5c9f8bdSJason M. Bills             "/redfish/v1/Systems/system/PCIeDevices/<str>/PCIeFunctions/<str>/",
268f5c9f8bdSJason M. Bills             std::string(), std::string())
269f5c9f8bdSJason M. Bills     {
270f5c9f8bdSJason M. Bills         entityPrivileges = {
271f5c9f8bdSJason M. Bills             {boost::beast::http::verb::get, {{"Login"}}},
272f5c9f8bdSJason M. Bills             {boost::beast::http::verb::head, {{"Login"}}},
273f5c9f8bdSJason M. Bills             {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
274f5c9f8bdSJason M. Bills             {boost::beast::http::verb::put, {{"ConfigureManager"}}},
275f5c9f8bdSJason M. Bills             {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
276f5c9f8bdSJason M. Bills             {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
277f5c9f8bdSJason M. Bills     }
278f5c9f8bdSJason M. Bills 
279f5c9f8bdSJason M. Bills   private:
280f5c9f8bdSJason M. Bills     void doGet(crow::Response &res, const crow::Request &req,
281f5c9f8bdSJason M. Bills                const std::vector<std::string> &params) override
282f5c9f8bdSJason M. Bills     {
283f5c9f8bdSJason M. Bills         std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
284f5c9f8bdSJason M. Bills         if (params.size() != 2)
285f5c9f8bdSJason M. Bills         {
286f5c9f8bdSJason M. Bills             messages::internalError(asyncResp->res);
287f5c9f8bdSJason M. Bills             return;
288f5c9f8bdSJason M. Bills         }
289f5c9f8bdSJason M. Bills         const std::string &device = params[0];
290f5c9f8bdSJason M. Bills         const std::string &function = params[1];
291f5c9f8bdSJason M. Bills 
292f5c9f8bdSJason M. Bills         auto getPCIeDeviceCallback =
293f5c9f8bdSJason M. Bills             [asyncResp, device, function](
294f5c9f8bdSJason M. Bills                 const boost::system::error_code ec,
295f5c9f8bdSJason M. Bills                 boost::container::flat_map<
296f5c9f8bdSJason M. Bills                     std::string, sdbusplus::message::variant<std::string>>
297f5c9f8bdSJason M. Bills                     &pcieDevProperties) {
298f5c9f8bdSJason M. Bills                 if (ec)
299f5c9f8bdSJason M. Bills                 {
300f5c9f8bdSJason M. Bills                     BMCWEB_LOG_DEBUG
301f5c9f8bdSJason M. Bills                         << "failed to get PCIe Device properties ec: "
302271584abSEd Tanous                         << ec.value() << ": " << ec.message();
303f5c9f8bdSJason M. Bills                     if (ec.value() ==
304f5c9f8bdSJason M. Bills                         boost::system::linux_error::bad_request_descriptor)
305f5c9f8bdSJason M. Bills                     {
306f5c9f8bdSJason M. Bills                         messages::resourceNotFound(asyncResp->res, "PCIeDevice",
307f5c9f8bdSJason M. Bills                                                    device);
308f5c9f8bdSJason M. Bills                     }
309f5c9f8bdSJason M. Bills                     else
310f5c9f8bdSJason M. Bills                     {
311f5c9f8bdSJason M. Bills                         messages::internalError(asyncResp->res);
312f5c9f8bdSJason M. Bills                     }
313f5c9f8bdSJason M. Bills                     return;
314f5c9f8bdSJason M. Bills                 }
315f5c9f8bdSJason M. Bills 
316f5c9f8bdSJason M. Bills                 // Check if this function exists by looking for a device ID
317f5c9f8bdSJason M. Bills                 std::string devIDProperty = "Function" + function + "DeviceId";
318f5c9f8bdSJason M. Bills                 if (std::string *property =
319f5c9f8bdSJason M. Bills                         sdbusplus::message::variant_ns::get_if<std::string>(
320f5c9f8bdSJason M. Bills                             &pcieDevProperties[devIDProperty]);
321f5c9f8bdSJason M. Bills                     property && property->empty())
322f5c9f8bdSJason M. Bills                 {
323f5c9f8bdSJason M. Bills                     messages::resourceNotFound(asyncResp->res, "PCIeFunction",
324f5c9f8bdSJason M. Bills                                                function);
325f5c9f8bdSJason M. Bills                     return;
326f5c9f8bdSJason M. Bills                 }
327f5c9f8bdSJason M. Bills 
328f5c9f8bdSJason M. Bills                 asyncResp->res.jsonValue = {
329f5c9f8bdSJason M. Bills                     {"@odata.type", "#PCIeFunction.v1_2_0.PCIeFunction"},
330f5c9f8bdSJason M. Bills                     {"@odata.context",
331f5c9f8bdSJason M. Bills                      "/redfish/v1/$metadata#PCIeFunction.PCIeFunction"},
332f5c9f8bdSJason M. Bills                     {"@odata.id", "/redfish/v1/Systems/system/PCIeDevices/" +
333f5c9f8bdSJason M. Bills                                       device + "/PCIeFunctions/" + function},
334f5c9f8bdSJason M. Bills                     {"Name", "PCIe Function"},
335f5c9f8bdSJason M. Bills                     {"Id", function},
336f5c9f8bdSJason M. Bills                     {"FunctionId", std::stoi(function)},
337f5c9f8bdSJason M. Bills                     {"Links",
338f5c9f8bdSJason M. Bills                      {{"PCIeDevice",
339f5c9f8bdSJason M. Bills                        {{"@odata.id",
340f5c9f8bdSJason M. Bills                          "/redfish/v1/Systems/system/PCIeDevices/" +
341f5c9f8bdSJason M. Bills                              device}}}}}};
342f5c9f8bdSJason M. Bills 
343f5c9f8bdSJason M. Bills                 if (std::string *property =
344f5c9f8bdSJason M. Bills                         sdbusplus::message::variant_ns::get_if<std::string>(
345f5c9f8bdSJason M. Bills                             &pcieDevProperties["Function" + function +
346f5c9f8bdSJason M. Bills                                                "DeviceId"]);
347f5c9f8bdSJason M. Bills                     property)
348f5c9f8bdSJason M. Bills                 {
349f5c9f8bdSJason M. Bills                     asyncResp->res.jsonValue["DeviceId"] = *property;
350f5c9f8bdSJason M. Bills                 }
351f5c9f8bdSJason M. Bills 
352f5c9f8bdSJason M. Bills                 if (std::string *property =
353f5c9f8bdSJason M. Bills                         sdbusplus::message::variant_ns::get_if<std::string>(
354f5c9f8bdSJason M. Bills                             &pcieDevProperties["Function" + function +
355f5c9f8bdSJason M. Bills                                                "VendorId"]);
356f5c9f8bdSJason M. Bills                     property)
357f5c9f8bdSJason M. Bills                 {
358f5c9f8bdSJason M. Bills                     asyncResp->res.jsonValue["VendorId"] = *property;
359f5c9f8bdSJason M. Bills                 }
360f5c9f8bdSJason M. Bills 
361f5c9f8bdSJason M. Bills                 if (std::string *property =
362f5c9f8bdSJason M. Bills                         sdbusplus::message::variant_ns::get_if<std::string>(
363f5c9f8bdSJason M. Bills                             &pcieDevProperties["Function" + function +
364f5c9f8bdSJason M. Bills                                                "FunctionType"]);
365f5c9f8bdSJason M. Bills                     property)
366f5c9f8bdSJason M. Bills                 {
367f5c9f8bdSJason M. Bills                     asyncResp->res.jsonValue["FunctionType"] = *property;
368f5c9f8bdSJason M. Bills                 }
369f5c9f8bdSJason M. Bills 
370f5c9f8bdSJason M. Bills                 if (std::string *property =
371f5c9f8bdSJason M. Bills                         sdbusplus::message::variant_ns::get_if<std::string>(
372f5c9f8bdSJason M. Bills                             &pcieDevProperties["Function" + function +
373f5c9f8bdSJason M. Bills                                                "DeviceClass"]);
374f5c9f8bdSJason M. Bills                     property)
375f5c9f8bdSJason M. Bills                 {
376f5c9f8bdSJason M. Bills                     asyncResp->res.jsonValue["DeviceClass"] = *property;
377f5c9f8bdSJason M. Bills                 }
378f5c9f8bdSJason M. Bills 
379f5c9f8bdSJason M. Bills                 if (std::string *property =
380f5c9f8bdSJason M. Bills                         sdbusplus::message::variant_ns::get_if<std::string>(
381f5c9f8bdSJason M. Bills                             &pcieDevProperties["Function" + function +
382f5c9f8bdSJason M. Bills                                                "ClassCode"]);
383f5c9f8bdSJason M. Bills                     property)
384f5c9f8bdSJason M. Bills                 {
385f5c9f8bdSJason M. Bills                     asyncResp->res.jsonValue["ClassCode"] = *property;
386f5c9f8bdSJason M. Bills                 }
387f5c9f8bdSJason M. Bills 
388f5c9f8bdSJason M. Bills                 if (std::string *property =
389f5c9f8bdSJason M. Bills                         sdbusplus::message::variant_ns::get_if<std::string>(
390f5c9f8bdSJason M. Bills                             &pcieDevProperties["Function" + function +
391f5c9f8bdSJason M. Bills                                                "RevisionId"]);
392f5c9f8bdSJason M. Bills                     property)
393f5c9f8bdSJason M. Bills                 {
394f5c9f8bdSJason M. Bills                     asyncResp->res.jsonValue["RevisionId"] = *property;
395f5c9f8bdSJason M. Bills                 }
396f5c9f8bdSJason M. Bills 
397f5c9f8bdSJason M. Bills                 if (std::string *property =
398f5c9f8bdSJason M. Bills                         sdbusplus::message::variant_ns::get_if<std::string>(
399f5c9f8bdSJason M. Bills                             &pcieDevProperties["Function" + function +
400f5c9f8bdSJason M. Bills                                                "SubsystemId"]);
401f5c9f8bdSJason M. Bills                     property)
402f5c9f8bdSJason M. Bills                 {
403f5c9f8bdSJason M. Bills                     asyncResp->res.jsonValue["SubsystemId"] = *property;
404f5c9f8bdSJason M. Bills                 }
405f5c9f8bdSJason M. Bills 
406f5c9f8bdSJason M. Bills                 if (std::string *property =
407f5c9f8bdSJason M. Bills                         sdbusplus::message::variant_ns::get_if<std::string>(
408f5c9f8bdSJason M. Bills                             &pcieDevProperties["Function" + function +
409f5c9f8bdSJason M. Bills                                                "SubsystemVendorId"]);
410f5c9f8bdSJason M. Bills                     property)
411f5c9f8bdSJason M. Bills                 {
412f5c9f8bdSJason M. Bills                     asyncResp->res.jsonValue["SubsystemVendorId"] = *property;
413f5c9f8bdSJason M. Bills                 }
414f5c9f8bdSJason M. Bills             };
415f5c9f8bdSJason M. Bills         std::string escapedPath = std::string(pciePath) + "/" + device;
416f5c9f8bdSJason M. Bills         dbus::utility::escapePathForDbus(escapedPath);
417f5c9f8bdSJason M. Bills         crow::connections::systemBus->async_method_call(
418f5c9f8bdSJason M. Bills             std::move(getPCIeDeviceCallback), pcieService, escapedPath,
419f5c9f8bdSJason M. Bills             "org.freedesktop.DBus.Properties", "GetAll", pcieDeviceInterface);
420f5c9f8bdSJason M. Bills     }
421f5c9f8bdSJason M. Bills };
422f5c9f8bdSJason M. Bills 
423f5c9f8bdSJason M. Bills } // namespace redfish
424