xref: /openbmc/bmcweb/features/redfish/lib/pcie.hpp (revision 271584ab78b4c1926f766aa26ddfde7da329059f)
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: "
111*271584abSEd 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 = {
126f5c9f8bdSJason M. Bills                     {"@odata.type", "#PCIeDevice.v1_2_0.PCIeDevice"},
127f5c9f8bdSJason M. Bills                     {"@odata.context",
128f5c9f8bdSJason M. Bills                      "/redfish/v1/$metadata#PCIeDevice.v1_2_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 
150f5c9f8bdSJason M. Bills                 nlohmann::json &pcieFunctionList =
151f5c9f8bdSJason M. Bills                     asyncResp->res.jsonValue["Links"]["PCIeFunctions"];
152f5c9f8bdSJason M. Bills                 pcieFunctionList = nlohmann::json::array();
153f5c9f8bdSJason M. Bills                 static constexpr const int maxPciFunctionNum = 8;
154f5c9f8bdSJason M. Bills                 for (int functionNum = 0; functionNum < maxPciFunctionNum;
155f5c9f8bdSJason M. Bills                      functionNum++)
156f5c9f8bdSJason M. Bills                 {
157f5c9f8bdSJason M. Bills                     // Check if this function exists by looking for a device ID
158f5c9f8bdSJason M. Bills                     std::string devIDProperty =
159f5c9f8bdSJason M. Bills                         "Function" + std::to_string(functionNum) + "DeviceId";
160f5c9f8bdSJason M. Bills                     if (std::string *property =
161f5c9f8bdSJason M. Bills                             sdbusplus::message::variant_ns::get_if<std::string>(
162f5c9f8bdSJason M. Bills                                 &pcieDevProperties[devIDProperty]);
163f5c9f8bdSJason M. Bills                         property && !property->empty())
164f5c9f8bdSJason M. Bills                     {
165f5c9f8bdSJason M. Bills                         pcieFunctionList.push_back(
166f5c9f8bdSJason M. Bills                             {{"@odata.id",
167f5c9f8bdSJason M. Bills                               "/redfish/v1/Systems/system/PCIeDevices/" +
168f5c9f8bdSJason M. Bills                                   device + "/PCIeFunctions/" +
169f5c9f8bdSJason M. Bills                                   std::to_string(functionNum)}});
170f5c9f8bdSJason M. Bills                     }
171f5c9f8bdSJason M. Bills                 }
172f5c9f8bdSJason M. Bills                 asyncResp->res.jsonValue["Links"]["PCIeFunctions@odata.count"] =
173f5c9f8bdSJason M. Bills                     pcieFunctionList.size();
174f5c9f8bdSJason M. Bills             };
175f5c9f8bdSJason M. Bills         std::string escapedPath = std::string(pciePath) + "/" + device;
176f5c9f8bdSJason M. Bills         dbus::utility::escapePathForDbus(escapedPath);
177f5c9f8bdSJason M. Bills         crow::connections::systemBus->async_method_call(
178f5c9f8bdSJason M. Bills             std::move(getPCIeDeviceCallback), pcieService, escapedPath,
179f5c9f8bdSJason M. Bills             "org.freedesktop.DBus.Properties", "GetAll", pcieDeviceInterface);
180f5c9f8bdSJason M. Bills     }
181f5c9f8bdSJason M. Bills };
182f5c9f8bdSJason M. Bills 
183f5c9f8bdSJason M. Bills class SystemPCIeFunction : public Node
184f5c9f8bdSJason M. Bills {
185f5c9f8bdSJason M. Bills   public:
186f5c9f8bdSJason M. Bills     SystemPCIeFunction(CrowApp &app) :
187f5c9f8bdSJason M. Bills         Node(
188f5c9f8bdSJason M. Bills             app,
189f5c9f8bdSJason M. Bills             "/redfish/v1/Systems/system/PCIeDevices/<str>/PCIeFunctions/<str>/",
190f5c9f8bdSJason M. Bills             std::string(), std::string())
191f5c9f8bdSJason M. Bills     {
192f5c9f8bdSJason M. Bills         entityPrivileges = {
193f5c9f8bdSJason M. Bills             {boost::beast::http::verb::get, {{"Login"}}},
194f5c9f8bdSJason M. Bills             {boost::beast::http::verb::head, {{"Login"}}},
195f5c9f8bdSJason M. Bills             {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
196f5c9f8bdSJason M. Bills             {boost::beast::http::verb::put, {{"ConfigureManager"}}},
197f5c9f8bdSJason M. Bills             {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
198f5c9f8bdSJason M. Bills             {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
199f5c9f8bdSJason M. Bills     }
200f5c9f8bdSJason M. Bills 
201f5c9f8bdSJason M. Bills   private:
202f5c9f8bdSJason M. Bills     void doGet(crow::Response &res, const crow::Request &req,
203f5c9f8bdSJason M. Bills                const std::vector<std::string> &params) override
204f5c9f8bdSJason M. Bills     {
205f5c9f8bdSJason M. Bills         std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
206f5c9f8bdSJason M. Bills         if (params.size() != 2)
207f5c9f8bdSJason M. Bills         {
208f5c9f8bdSJason M. Bills             messages::internalError(asyncResp->res);
209f5c9f8bdSJason M. Bills             return;
210f5c9f8bdSJason M. Bills         }
211f5c9f8bdSJason M. Bills         const std::string &device = params[0];
212f5c9f8bdSJason M. Bills         const std::string &function = params[1];
213f5c9f8bdSJason M. Bills 
214f5c9f8bdSJason M. Bills         auto getPCIeDeviceCallback =
215f5c9f8bdSJason M. Bills             [asyncResp, device, function](
216f5c9f8bdSJason M. Bills                 const boost::system::error_code ec,
217f5c9f8bdSJason M. Bills                 boost::container::flat_map<
218f5c9f8bdSJason M. Bills                     std::string, sdbusplus::message::variant<std::string>>
219f5c9f8bdSJason M. Bills                     &pcieDevProperties) {
220f5c9f8bdSJason M. Bills                 if (ec)
221f5c9f8bdSJason M. Bills                 {
222f5c9f8bdSJason M. Bills                     BMCWEB_LOG_DEBUG
223f5c9f8bdSJason M. Bills                         << "failed to get PCIe Device properties ec: "
224*271584abSEd Tanous                         << ec.value() << ": " << ec.message();
225f5c9f8bdSJason M. Bills                     if (ec.value() ==
226f5c9f8bdSJason M. Bills                         boost::system::linux_error::bad_request_descriptor)
227f5c9f8bdSJason M. Bills                     {
228f5c9f8bdSJason M. Bills                         messages::resourceNotFound(asyncResp->res, "PCIeDevice",
229f5c9f8bdSJason M. Bills                                                    device);
230f5c9f8bdSJason M. Bills                     }
231f5c9f8bdSJason M. Bills                     else
232f5c9f8bdSJason M. Bills                     {
233f5c9f8bdSJason M. Bills                         messages::internalError(asyncResp->res);
234f5c9f8bdSJason M. Bills                     }
235f5c9f8bdSJason M. Bills                     return;
236f5c9f8bdSJason M. Bills                 }
237f5c9f8bdSJason M. Bills 
238f5c9f8bdSJason M. Bills                 // Check if this function exists by looking for a device ID
239f5c9f8bdSJason M. Bills                 std::string devIDProperty = "Function" + function + "DeviceId";
240f5c9f8bdSJason M. Bills                 if (std::string *property =
241f5c9f8bdSJason M. Bills                         sdbusplus::message::variant_ns::get_if<std::string>(
242f5c9f8bdSJason M. Bills                             &pcieDevProperties[devIDProperty]);
243f5c9f8bdSJason M. Bills                     property && property->empty())
244f5c9f8bdSJason M. Bills                 {
245f5c9f8bdSJason M. Bills                     messages::resourceNotFound(asyncResp->res, "PCIeFunction",
246f5c9f8bdSJason M. Bills                                                function);
247f5c9f8bdSJason M. Bills                     return;
248f5c9f8bdSJason M. Bills                 }
249f5c9f8bdSJason M. Bills 
250f5c9f8bdSJason M. Bills                 asyncResp->res.jsonValue = {
251f5c9f8bdSJason M. Bills                     {"@odata.type", "#PCIeFunction.v1_2_0.PCIeFunction"},
252f5c9f8bdSJason M. Bills                     {"@odata.context",
253f5c9f8bdSJason M. Bills                      "/redfish/v1/$metadata#PCIeFunction.PCIeFunction"},
254f5c9f8bdSJason M. Bills                     {"@odata.id", "/redfish/v1/Systems/system/PCIeDevices/" +
255f5c9f8bdSJason M. Bills                                       device + "/PCIeFunctions/" + function},
256f5c9f8bdSJason M. Bills                     {"Name", "PCIe Function"},
257f5c9f8bdSJason M. Bills                     {"Id", function},
258f5c9f8bdSJason M. Bills                     {"FunctionId", std::stoi(function)},
259f5c9f8bdSJason M. Bills                     {"Links",
260f5c9f8bdSJason M. Bills                      {{"PCIeDevice",
261f5c9f8bdSJason M. Bills                        {{"@odata.id",
262f5c9f8bdSJason M. Bills                          "/redfish/v1/Systems/system/PCIeDevices/" +
263f5c9f8bdSJason M. Bills                              device}}}}}};
264f5c9f8bdSJason M. Bills 
265f5c9f8bdSJason M. Bills                 if (std::string *property =
266f5c9f8bdSJason M. Bills                         sdbusplus::message::variant_ns::get_if<std::string>(
267f5c9f8bdSJason M. Bills                             &pcieDevProperties["Function" + function +
268f5c9f8bdSJason M. Bills                                                "DeviceId"]);
269f5c9f8bdSJason M. Bills                     property)
270f5c9f8bdSJason M. Bills                 {
271f5c9f8bdSJason M. Bills                     asyncResp->res.jsonValue["DeviceId"] = *property;
272f5c9f8bdSJason M. Bills                 }
273f5c9f8bdSJason M. Bills 
274f5c9f8bdSJason M. Bills                 if (std::string *property =
275f5c9f8bdSJason M. Bills                         sdbusplus::message::variant_ns::get_if<std::string>(
276f5c9f8bdSJason M. Bills                             &pcieDevProperties["Function" + function +
277f5c9f8bdSJason M. Bills                                                "VendorId"]);
278f5c9f8bdSJason M. Bills                     property)
279f5c9f8bdSJason M. Bills                 {
280f5c9f8bdSJason M. Bills                     asyncResp->res.jsonValue["VendorId"] = *property;
281f5c9f8bdSJason M. Bills                 }
282f5c9f8bdSJason M. Bills 
283f5c9f8bdSJason M. Bills                 if (std::string *property =
284f5c9f8bdSJason M. Bills                         sdbusplus::message::variant_ns::get_if<std::string>(
285f5c9f8bdSJason M. Bills                             &pcieDevProperties["Function" + function +
286f5c9f8bdSJason M. Bills                                                "FunctionType"]);
287f5c9f8bdSJason M. Bills                     property)
288f5c9f8bdSJason M. Bills                 {
289f5c9f8bdSJason M. Bills                     asyncResp->res.jsonValue["FunctionType"] = *property;
290f5c9f8bdSJason M. Bills                 }
291f5c9f8bdSJason M. Bills 
292f5c9f8bdSJason M. Bills                 if (std::string *property =
293f5c9f8bdSJason M. Bills                         sdbusplus::message::variant_ns::get_if<std::string>(
294f5c9f8bdSJason M. Bills                             &pcieDevProperties["Function" + function +
295f5c9f8bdSJason M. Bills                                                "DeviceClass"]);
296f5c9f8bdSJason M. Bills                     property)
297f5c9f8bdSJason M. Bills                 {
298f5c9f8bdSJason M. Bills                     asyncResp->res.jsonValue["DeviceClass"] = *property;
299f5c9f8bdSJason M. Bills                 }
300f5c9f8bdSJason M. Bills 
301f5c9f8bdSJason M. Bills                 if (std::string *property =
302f5c9f8bdSJason M. Bills                         sdbusplus::message::variant_ns::get_if<std::string>(
303f5c9f8bdSJason M. Bills                             &pcieDevProperties["Function" + function +
304f5c9f8bdSJason M. Bills                                                "ClassCode"]);
305f5c9f8bdSJason M. Bills                     property)
306f5c9f8bdSJason M. Bills                 {
307f5c9f8bdSJason M. Bills                     asyncResp->res.jsonValue["ClassCode"] = *property;
308f5c9f8bdSJason M. Bills                 }
309f5c9f8bdSJason M. Bills 
310f5c9f8bdSJason M. Bills                 if (std::string *property =
311f5c9f8bdSJason M. Bills                         sdbusplus::message::variant_ns::get_if<std::string>(
312f5c9f8bdSJason M. Bills                             &pcieDevProperties["Function" + function +
313f5c9f8bdSJason M. Bills                                                "RevisionId"]);
314f5c9f8bdSJason M. Bills                     property)
315f5c9f8bdSJason M. Bills                 {
316f5c9f8bdSJason M. Bills                     asyncResp->res.jsonValue["RevisionId"] = *property;
317f5c9f8bdSJason M. Bills                 }
318f5c9f8bdSJason M. Bills 
319f5c9f8bdSJason M. Bills                 if (std::string *property =
320f5c9f8bdSJason M. Bills                         sdbusplus::message::variant_ns::get_if<std::string>(
321f5c9f8bdSJason M. Bills                             &pcieDevProperties["Function" + function +
322f5c9f8bdSJason M. Bills                                                "SubsystemId"]);
323f5c9f8bdSJason M. Bills                     property)
324f5c9f8bdSJason M. Bills                 {
325f5c9f8bdSJason M. Bills                     asyncResp->res.jsonValue["SubsystemId"] = *property;
326f5c9f8bdSJason M. Bills                 }
327f5c9f8bdSJason M. Bills 
328f5c9f8bdSJason M. Bills                 if (std::string *property =
329f5c9f8bdSJason M. Bills                         sdbusplus::message::variant_ns::get_if<std::string>(
330f5c9f8bdSJason M. Bills                             &pcieDevProperties["Function" + function +
331f5c9f8bdSJason M. Bills                                                "SubsystemVendorId"]);
332f5c9f8bdSJason M. Bills                     property)
333f5c9f8bdSJason M. Bills                 {
334f5c9f8bdSJason M. Bills                     asyncResp->res.jsonValue["SubsystemVendorId"] = *property;
335f5c9f8bdSJason M. Bills                 }
336f5c9f8bdSJason M. Bills             };
337f5c9f8bdSJason M. Bills         std::string escapedPath = std::string(pciePath) + "/" + device;
338f5c9f8bdSJason M. Bills         dbus::utility::escapePathForDbus(escapedPath);
339f5c9f8bdSJason M. Bills         crow::connections::systemBus->async_method_call(
340f5c9f8bdSJason M. Bills             std::move(getPCIeDeviceCallback), pcieService, escapedPath,
341f5c9f8bdSJason M. Bills             "org.freedesktop.DBus.Properties", "GetAll", pcieDeviceInterface);
342f5c9f8bdSJason M. Bills     }
343f5c9f8bdSJason M. Bills };
344f5c9f8bdSJason M. Bills 
345f5c9f8bdSJason M. Bills } // namespace redfish
346