xref: /openbmc/bmcweb/features/redfish/lib/pcie.hpp (revision 62cd45af311e7741064c114581ba34186d6e508c)
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 
197e860f15SJohn Edward Broadbent #include <app.hpp>
20f5c9f8bdSJason M. Bills #include <boost/system/linux_error.hpp>
21ed398213SEd Tanous #include <registries/privilege_registry.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 
31b5a76932SEd Tanous static inline void
328d1b46d7Szhanghch05     getPCIeDeviceList(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
33adbe192aSJason M. Bills                       const std::string& name)
34f5c9f8bdSJason M. Bills {
35adbe192aSJason M. Bills     auto getPCIeMapCallback = [asyncResp, name](
36adbe192aSJason M. Bills                                   const boost::system::error_code ec,
37f5c9f8bdSJason M. Bills                                   std::vector<std::string>& pcieDevicePaths) {
38f5c9f8bdSJason M. Bills         if (ec)
39f5c9f8bdSJason M. Bills         {
40a2730f01SAndrew Geissler             BMCWEB_LOG_DEBUG << "no PCIe device paths found ec: "
41f5c9f8bdSJason M. Bills                              << ec.message();
42a2730f01SAndrew Geissler             // Not an error, system just doesn't have PCIe info
43f5c9f8bdSJason M. Bills             return;
44f5c9f8bdSJason M. Bills         }
45adbe192aSJason M. Bills         nlohmann::json& pcieDeviceList = asyncResp->res.jsonValue[name];
46f5c9f8bdSJason M. Bills         pcieDeviceList = nlohmann::json::array();
47f5c9f8bdSJason M. Bills         for (const std::string& pcieDevicePath : pcieDevicePaths)
48f5c9f8bdSJason M. Bills         {
493174e4dfSEd Tanous             size_t devStart = pcieDevicePath.rfind('/');
50f5c9f8bdSJason M. Bills             if (devStart == std::string::npos)
51f5c9f8bdSJason M. Bills             {
52f5c9f8bdSJason M. Bills                 continue;
53f5c9f8bdSJason M. Bills             }
54f5c9f8bdSJason M. Bills 
55f5c9f8bdSJason M. Bills             std::string devName = pcieDevicePath.substr(devStart + 1);
56f5c9f8bdSJason M. Bills             if (devName.empty())
57f5c9f8bdSJason M. Bills             {
58f5c9f8bdSJason M. Bills                 continue;
59f5c9f8bdSJason M. Bills             }
60f5c9f8bdSJason M. Bills             pcieDeviceList.push_back(
61f5c9f8bdSJason M. Bills                 {{"@odata.id",
62f5c9f8bdSJason M. Bills                   "/redfish/v1/Systems/system/PCIeDevices/" + devName}});
63f5c9f8bdSJason M. Bills         }
64adbe192aSJason M. Bills         asyncResp->res.jsonValue[name + "@odata.count"] = 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 
737e860f15SJohn Edward Broadbent inline void requestRoutesSystemPCIeDeviceCollection(App& app)
74adbe192aSJason M. Bills {
75adbe192aSJason M. Bills     /**
76adbe192aSJason M. Bills      * Functions triggers appropriate requests on DBus
77adbe192aSJason M. Bills      */
787e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/PCIeDevices/")
79ed398213SEd Tanous         .privileges(redfish::privileges::getPCIeDeviceCollection)
807e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
817e860f15SJohn Edward Broadbent             [](const crow::Request&,
827e860f15SJohn Edward Broadbent                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
837e860f15SJohn Edward Broadbent 
84adbe192aSJason M. Bills             {
85adbe192aSJason M. Bills                 asyncResp->res.jsonValue = {
867e860f15SJohn Edward Broadbent                     {"@odata.type",
877e860f15SJohn Edward Broadbent                      "#PCIeDeviceCollection.PCIeDeviceCollection"},
88adbe192aSJason M. Bills                     {"@odata.id", "/redfish/v1/Systems/system/PCIeDevices"},
89adbe192aSJason M. Bills                     {"Name", "PCIe Device Collection"},
90adbe192aSJason M. Bills                     {"Description", "Collection of PCIe Devices"},
91adbe192aSJason M. Bills                     {"Members", nlohmann::json::array()},
92adbe192aSJason M. Bills                     {"Members@odata.count", 0}};
93adbe192aSJason M. Bills                 getPCIeDeviceList(asyncResp, "Members");
947e860f15SJohn Edward Broadbent             });
95f5c9f8bdSJason M. Bills }
96f5c9f8bdSJason M. Bills 
97*62cd45afSSpencer Ku inline std::optional<std::string>
98*62cd45afSSpencer Ku     redfishPcieGenerationFromDbus(const std::string& generationInUse)
99*62cd45afSSpencer Ku {
100*62cd45afSSpencer Ku     if (generationInUse ==
101*62cd45afSSpencer Ku         "xyz.openbmc_project.Inventory.Item.PCIeSlot.Generations.Gen1")
102*62cd45afSSpencer Ku     {
103*62cd45afSSpencer Ku         return "Gen1";
104*62cd45afSSpencer Ku     }
105*62cd45afSSpencer Ku     if (generationInUse ==
106*62cd45afSSpencer Ku         "xyz.openbmc_project.Inventory.Item.PCIeSlot.Generations.Gen2")
107*62cd45afSSpencer Ku     {
108*62cd45afSSpencer Ku         return "Gen2";
109*62cd45afSSpencer Ku     }
110*62cd45afSSpencer Ku     if (generationInUse ==
111*62cd45afSSpencer Ku         "xyz.openbmc_project.Inventory.Item.PCIeSlot.Generations.Gen3")
112*62cd45afSSpencer Ku     {
113*62cd45afSSpencer Ku         return "Gen3";
114*62cd45afSSpencer Ku     }
115*62cd45afSSpencer Ku     if (generationInUse ==
116*62cd45afSSpencer Ku         "xyz.openbmc_project.Inventory.Item.PCIeSlot.Generations.Gen4")
117*62cd45afSSpencer Ku     {
118*62cd45afSSpencer Ku         return "Gen4";
119*62cd45afSSpencer Ku     }
120*62cd45afSSpencer Ku     if (generationInUse ==
121*62cd45afSSpencer Ku         "xyz.openbmc_project.Inventory.Item.PCIeSlot.Generations.Gen5")
122*62cd45afSSpencer Ku     {
123*62cd45afSSpencer Ku         return "Gen5";
124*62cd45afSSpencer Ku     }
125*62cd45afSSpencer Ku     if (generationInUse.empty() ||
126*62cd45afSSpencer Ku         generationInUse ==
127*62cd45afSSpencer Ku             "xyz.openbmc_project.Inventory.Item.PCIeSlot.Generations.Unknown")
128*62cd45afSSpencer Ku     {
129*62cd45afSSpencer Ku         return "";
130*62cd45afSSpencer Ku     }
131*62cd45afSSpencer Ku 
132*62cd45afSSpencer Ku     // The value is not unknown or Gen1-5, need return an internal error.
133*62cd45afSSpencer Ku     return std::nullopt;
134*62cd45afSSpencer Ku }
135*62cd45afSSpencer Ku 
1367e860f15SJohn Edward Broadbent inline void requestRoutesSystemPCIeDevice(App& app)
137f5c9f8bdSJason M. Bills {
1387e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/PCIeDevices/<str>/")
139ed398213SEd Tanous         .privileges(redfish::privileges::getPCIeDevice)
1407e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
1417e860f15SJohn Edward Broadbent             [](const crow::Request&,
1427e860f15SJohn Edward Broadbent                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1437e860f15SJohn Edward Broadbent                const std::string& device)
144f5c9f8bdSJason M. Bills 
1457e860f15SJohn Edward Broadbent             {
1467e860f15SJohn Edward Broadbent                 auto getPCIeDeviceCallback = [asyncResp, device](
1477e860f15SJohn Edward Broadbent                                                  const boost::system::error_code
1487e860f15SJohn Edward Broadbent                                                      ec,
1497e860f15SJohn Edward Broadbent                                                  boost::container::flat_map<
1507e860f15SJohn Edward Broadbent                                                      std::string,
1511214b7e7SGunnar Mills                                                      std::variant<std::string>>&
1521214b7e7SGunnar Mills                                                      pcieDevProperties) {
153f5c9f8bdSJason M. Bills                     if (ec)
154f5c9f8bdSJason M. Bills                     {
155f5c9f8bdSJason M. Bills                         BMCWEB_LOG_DEBUG
156f5c9f8bdSJason M. Bills                             << "failed to get PCIe Device properties ec: "
157271584abSEd Tanous                             << ec.value() << ": " << ec.message();
158f5c9f8bdSJason M. Bills                         if (ec.value() ==
159f5c9f8bdSJason M. Bills                             boost::system::linux_error::bad_request_descriptor)
160f5c9f8bdSJason M. Bills                         {
1617e860f15SJohn Edward Broadbent                             messages::resourceNotFound(asyncResp->res,
1627e860f15SJohn Edward Broadbent                                                        "PCIeDevice", device);
163f5c9f8bdSJason M. Bills                         }
164f5c9f8bdSJason M. Bills                         else
165f5c9f8bdSJason M. Bills                         {
166f5c9f8bdSJason M. Bills                             messages::internalError(asyncResp->res);
167f5c9f8bdSJason M. Bills                         }
168f5c9f8bdSJason M. Bills                         return;
169f5c9f8bdSJason M. Bills                     }
170f5c9f8bdSJason M. Bills 
171f5c9f8bdSJason M. Bills                     asyncResp->res.jsonValue = {
172dede6a98SJason M. Bills                         {"@odata.type", "#PCIeDevice.v1_4_0.PCIeDevice"},
173f5c9f8bdSJason M. Bills                         {"@odata.id",
174f5c9f8bdSJason M. Bills                          "/redfish/v1/Systems/system/PCIeDevices/" + device},
175f5c9f8bdSJason M. Bills                         {"Name", "PCIe Device"},
176f5c9f8bdSJason M. Bills                         {"Id", device}};
177f5c9f8bdSJason M. Bills 
1788d78b7a9SPatrick Williams                     if (std::string* property = std::get_if<std::string>(
179f5c9f8bdSJason M. Bills                             &pcieDevProperties["Manufacturer"]);
180f5c9f8bdSJason M. Bills                         property)
181f5c9f8bdSJason M. Bills                     {
182f5c9f8bdSJason M. Bills                         asyncResp->res.jsonValue["Manufacturer"] = *property;
183f5c9f8bdSJason M. Bills                     }
184f5c9f8bdSJason M. Bills 
1858d78b7a9SPatrick Williams                     if (std::string* property = std::get_if<std::string>(
186f5c9f8bdSJason M. Bills                             &pcieDevProperties["DeviceType"]);
187f5c9f8bdSJason M. Bills                         property)
188f5c9f8bdSJason M. Bills                     {
189f5c9f8bdSJason M. Bills                         asyncResp->res.jsonValue["DeviceType"] = *property;
190f5c9f8bdSJason M. Bills                     }
191f5c9f8bdSJason M. Bills 
192*62cd45afSSpencer Ku                     if (std::string* property = std::get_if<std::string>(
193*62cd45afSSpencer Ku                             &pcieDevProperties["GenerationInUse"]);
194*62cd45afSSpencer Ku                         property)
195*62cd45afSSpencer Ku                     {
196*62cd45afSSpencer Ku                         std::optional<std::string> generationInUse =
197*62cd45afSSpencer Ku                             redfishPcieGenerationFromDbus(*property);
198*62cd45afSSpencer Ku                         if (!generationInUse)
199*62cd45afSSpencer Ku                         {
200*62cd45afSSpencer Ku                             messages::internalError(asyncResp->res);
201*62cd45afSSpencer Ku                             return;
202*62cd45afSSpencer Ku                         }
203*62cd45afSSpencer Ku                         if (*generationInUse == "")
204*62cd45afSSpencer Ku                         {
205*62cd45afSSpencer Ku                             // unknown, no need to handle
206*62cd45afSSpencer Ku                             return;
207*62cd45afSSpencer Ku                         }
208*62cd45afSSpencer Ku                         asyncResp->res.jsonValue["PCIeInterface"]["PcieType"] =
209*62cd45afSSpencer Ku                             *generationInUse;
210*62cd45afSSpencer Ku                     }
211dede6a98SJason M. Bills                     asyncResp->res.jsonValue["PCIeFunctions"] = {
2127e860f15SJohn Edward Broadbent                         {"@odata.id",
2137e860f15SJohn Edward Broadbent                          "/redfish/v1/Systems/system/PCIeDevices/" + device +
2147e860f15SJohn Edward Broadbent                              "/PCIeFunctions"}};
215dede6a98SJason M. Bills                 };
216dede6a98SJason M. Bills                 std::string escapedPath = std::string(pciePath) + "/" + device;
217dede6a98SJason M. Bills                 dbus::utility::escapePathForDbus(escapedPath);
218dede6a98SJason M. Bills                 crow::connections::systemBus->async_method_call(
219dede6a98SJason M. Bills                     std::move(getPCIeDeviceCallback), pcieService, escapedPath,
2207e860f15SJohn Edward Broadbent                     "org.freedesktop.DBus.Properties", "GetAll",
2217e860f15SJohn Edward Broadbent                     pcieDeviceInterface);
2227e860f15SJohn Edward Broadbent             });
223dede6a98SJason M. Bills }
224dede6a98SJason M. Bills 
2257e860f15SJohn Edward Broadbent inline void requestRoutesSystemPCIeFunctionCollection(App& app)
2267e860f15SJohn Edward Broadbent {
227dede6a98SJason M. Bills     /**
228dede6a98SJason M. Bills      * Functions triggers appropriate requests on DBus
229dede6a98SJason M. Bills      */
2307e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app,
2317e860f15SJohn Edward Broadbent                  "/redfish/v1/Systems/system/PCIeDevices/<str>/PCIeFunctions/")
232ed398213SEd Tanous         .privileges(redfish::privileges::getPCIeFunctionCollection)
2337e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
2347e860f15SJohn Edward Broadbent             [](const crow::Request&,
2357e860f15SJohn Edward Broadbent                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2367e860f15SJohn Edward Broadbent                const std::string& device)
2377e860f15SJohn Edward Broadbent 
238dede6a98SJason M. Bills             {
239dede6a98SJason M. Bills                 asyncResp->res.jsonValue = {
2407e860f15SJohn Edward Broadbent                     {"@odata.type",
2417e860f15SJohn Edward Broadbent                      "#PCIeFunctionCollection.PCIeFunctionCollection"},
2427e860f15SJohn Edward Broadbent                     {"@odata.id", "/redfish/v1/Systems/system/PCIeDevices/" +
2437e860f15SJohn Edward Broadbent                                       device + "/PCIeFunctions"},
244dede6a98SJason M. Bills                     {"Name", "PCIe Function Collection"},
245dede6a98SJason M. Bills                     {"Description",
246dede6a98SJason M. Bills                      "Collection of PCIe Functions for PCIe Device " + device}};
247dede6a98SJason M. Bills 
2487e860f15SJohn Edward Broadbent                 auto getPCIeDeviceCallback = [asyncResp, device](
2497e860f15SJohn Edward Broadbent                                                  const boost::system::error_code
2507e860f15SJohn Edward Broadbent                                                      ec,
2517e860f15SJohn Edward Broadbent                                                  boost::container::flat_map<
2527e860f15SJohn Edward Broadbent                                                      std::string,
2537e860f15SJohn Edward Broadbent                                                      std::variant<std::string>>&
2547e860f15SJohn Edward Broadbent                                                      pcieDevProperties) {
2557e860f15SJohn Edward Broadbent                     if (ec)
2567e860f15SJohn Edward Broadbent                     {
2577e860f15SJohn Edward Broadbent                         BMCWEB_LOG_DEBUG
2587e860f15SJohn Edward Broadbent                             << "failed to get PCIe Device properties ec: "
2597e860f15SJohn Edward Broadbent                             << ec.value() << ": " << ec.message();
2607e860f15SJohn Edward Broadbent                         if (ec.value() ==
2617e860f15SJohn Edward Broadbent                             boost::system::linux_error::bad_request_descriptor)
2627e860f15SJohn Edward Broadbent                         {
2637e860f15SJohn Edward Broadbent                             messages::resourceNotFound(asyncResp->res,
2647e860f15SJohn Edward Broadbent                                                        "PCIeDevice", device);
2657e860f15SJohn Edward Broadbent                         }
2667e860f15SJohn Edward Broadbent                         else
2677e860f15SJohn Edward Broadbent                         {
2687e860f15SJohn Edward Broadbent                             messages::internalError(asyncResp->res);
2697e860f15SJohn Edward Broadbent                         }
2707e860f15SJohn Edward Broadbent                         return;
2717e860f15SJohn Edward Broadbent                     }
2727e860f15SJohn Edward Broadbent 
2737e860f15SJohn Edward Broadbent                     nlohmann::json& pcieFunctionList =
2747e860f15SJohn Edward Broadbent                         asyncResp->res.jsonValue["Members"];
2757e860f15SJohn Edward Broadbent                     pcieFunctionList = nlohmann::json::array();
2767e860f15SJohn Edward Broadbent                     static constexpr const int maxPciFunctionNum = 8;
2777e860f15SJohn Edward Broadbent                     for (int functionNum = 0; functionNum < maxPciFunctionNum;
2787e860f15SJohn Edward Broadbent                          functionNum++)
2797e860f15SJohn Edward Broadbent                     {
2807e860f15SJohn Edward Broadbent                         // Check if this function exists by looking for a device
2817e860f15SJohn Edward Broadbent                         // ID
2827e860f15SJohn Edward Broadbent                         std::string devIDProperty =
2837e860f15SJohn Edward Broadbent                             "Function" + std::to_string(functionNum) +
2847e860f15SJohn Edward Broadbent                             "DeviceId";
2857e860f15SJohn Edward Broadbent                         std::string* property = std::get_if<std::string>(
2867e860f15SJohn Edward Broadbent                             &pcieDevProperties[devIDProperty]);
2877e860f15SJohn Edward Broadbent                         if (property && !property->empty())
2887e860f15SJohn Edward Broadbent                         {
2897e860f15SJohn Edward Broadbent                             pcieFunctionList.push_back(
2907e860f15SJohn Edward Broadbent                                 {{"@odata.id",
2917e860f15SJohn Edward Broadbent                                   "/redfish/v1/Systems/system/PCIeDevices/" +
2927e860f15SJohn Edward Broadbent                                       device + "/PCIeFunctions/" +
2937e860f15SJohn Edward Broadbent                                       std::to_string(functionNum)}});
2947e860f15SJohn Edward Broadbent                         }
2957e860f15SJohn Edward Broadbent                     }
2967e860f15SJohn Edward Broadbent                     asyncResp->res.jsonValue["PCIeFunctions@odata.count"] =
2977e860f15SJohn Edward Broadbent                         pcieFunctionList.size();
2987e860f15SJohn Edward Broadbent                 };
2997e860f15SJohn Edward Broadbent                 std::string escapedPath = std::string(pciePath) + "/" + device;
3007e860f15SJohn Edward Broadbent                 dbus::utility::escapePathForDbus(escapedPath);
3017e860f15SJohn Edward Broadbent                 crow::connections::systemBus->async_method_call(
3027e860f15SJohn Edward Broadbent                     std::move(getPCIeDeviceCallback), pcieService, escapedPath,
3037e860f15SJohn Edward Broadbent                     "org.freedesktop.DBus.Properties", "GetAll",
3047e860f15SJohn Edward Broadbent                     pcieDeviceInterface);
3057e860f15SJohn Edward Broadbent             });
3067e860f15SJohn Edward Broadbent }
3077e860f15SJohn Edward Broadbent 
3087e860f15SJohn Edward Broadbent inline void requestRoutesSystemPCIeFunction(App& app)
3097e860f15SJohn Edward Broadbent {
3107e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(
3117e860f15SJohn Edward Broadbent         app,
3127e860f15SJohn Edward Broadbent         "/redfish/v1/Systems/system/PCIeDevices/<str>/PCIeFunctions/<str>/")
313ed398213SEd Tanous         .privileges(redfish::privileges::getPCIeFunction)
3147e860f15SJohn Edward Broadbent         .methods(
3157e860f15SJohn Edward Broadbent             boost::beast::http::verb::get)([](const crow::Request&,
3167e860f15SJohn Edward Broadbent                                               const std::shared_ptr<
3177e860f15SJohn Edward Broadbent                                                   bmcweb::AsyncResp>& asyncResp,
3187e860f15SJohn Edward Broadbent                                               const std::string& device,
3197e860f15SJohn Edward Broadbent                                               const std::string& function) {
3207e860f15SJohn Edward Broadbent             auto getPCIeDeviceCallback = [asyncResp, device, function](
3217e860f15SJohn Edward Broadbent                                              const boost::system::error_code ec,
3227e860f15SJohn Edward Broadbent                                              boost::container::flat_map<
3237e860f15SJohn Edward Broadbent                                                  std::string,
3241214b7e7SGunnar Mills                                                  std::variant<std::string>>&
3251214b7e7SGunnar Mills                                                  pcieDevProperties) {
326dede6a98SJason M. Bills                 if (ec)
327dede6a98SJason M. Bills                 {
328dede6a98SJason M. Bills                     BMCWEB_LOG_DEBUG
329dede6a98SJason M. Bills                         << "failed to get PCIe Device properties ec: "
330dede6a98SJason M. Bills                         << ec.value() << ": " << ec.message();
331dede6a98SJason M. Bills                     if (ec.value() ==
332dede6a98SJason M. Bills                         boost::system::linux_error::bad_request_descriptor)
333dede6a98SJason M. Bills                     {
334dede6a98SJason M. Bills                         messages::resourceNotFound(asyncResp->res, "PCIeDevice",
335dede6a98SJason M. Bills                                                    device);
336dede6a98SJason M. Bills                     }
337dede6a98SJason M. Bills                     else
338dede6a98SJason M. Bills                     {
339dede6a98SJason M. Bills                         messages::internalError(asyncResp->res);
340dede6a98SJason M. Bills                     }
341dede6a98SJason M. Bills                     return;
342dede6a98SJason M. Bills                 }
343dede6a98SJason M. Bills 
344f5c9f8bdSJason M. Bills                 // Check if this function exists by looking for a device ID
345f5c9f8bdSJason M. Bills                 std::string devIDProperty = "Function" + function + "DeviceId";
3467e860f15SJohn Edward Broadbent                 if (std::string* property = std::get_if<std::string>(
3477e860f15SJohn Edward Broadbent                         &pcieDevProperties[devIDProperty]);
348f5c9f8bdSJason M. Bills                     property && property->empty())
349f5c9f8bdSJason M. Bills                 {
350f5c9f8bdSJason M. Bills                     messages::resourceNotFound(asyncResp->res, "PCIeFunction",
351f5c9f8bdSJason M. Bills                                                function);
352f5c9f8bdSJason M. Bills                     return;
353f5c9f8bdSJason M. Bills                 }
354f5c9f8bdSJason M. Bills 
355f5c9f8bdSJason M. Bills                 asyncResp->res.jsonValue = {
356f5c9f8bdSJason M. Bills                     {"@odata.type", "#PCIeFunction.v1_2_0.PCIeFunction"},
357f5c9f8bdSJason M. Bills                     {"@odata.id", "/redfish/v1/Systems/system/PCIeDevices/" +
358f5c9f8bdSJason M. Bills                                       device + "/PCIeFunctions/" + function},
359f5c9f8bdSJason M. Bills                     {"Name", "PCIe Function"},
360f5c9f8bdSJason M. Bills                     {"Id", function},
361f5c9f8bdSJason M. Bills                     {"FunctionId", std::stoi(function)},
362f5c9f8bdSJason M. Bills                     {"Links",
363f5c9f8bdSJason M. Bills                      {{"PCIeDevice",
364f5c9f8bdSJason M. Bills                        {{"@odata.id",
3657e860f15SJohn Edward Broadbent                          "/redfish/v1/Systems/system/PCIeDevices/" +
3667e860f15SJohn Edward Broadbent                              device}}}}}};
367f5c9f8bdSJason M. Bills 
3688d78b7a9SPatrick Williams                 if (std::string* property = std::get_if<std::string>(
3698d78b7a9SPatrick Williams                         &pcieDevProperties["Function" + function + "DeviceId"]);
370f5c9f8bdSJason M. Bills                     property)
371f5c9f8bdSJason M. Bills                 {
372f5c9f8bdSJason M. Bills                     asyncResp->res.jsonValue["DeviceId"] = *property;
373f5c9f8bdSJason M. Bills                 }
374f5c9f8bdSJason M. Bills 
3758d78b7a9SPatrick Williams                 if (std::string* property = std::get_if<std::string>(
3768d78b7a9SPatrick Williams                         &pcieDevProperties["Function" + function + "VendorId"]);
377f5c9f8bdSJason M. Bills                     property)
378f5c9f8bdSJason M. Bills                 {
379f5c9f8bdSJason M. Bills                     asyncResp->res.jsonValue["VendorId"] = *property;
380f5c9f8bdSJason M. Bills                 }
381f5c9f8bdSJason M. Bills 
3828d78b7a9SPatrick Williams                 if (std::string* property = std::get_if<std::string>(
3837e860f15SJohn Edward Broadbent                         &pcieDevProperties["Function" + function +
3847e860f15SJohn Edward Broadbent                                            "FunctionType"]);
385f5c9f8bdSJason M. Bills                     property)
386f5c9f8bdSJason M. Bills                 {
387f5c9f8bdSJason M. Bills                     asyncResp->res.jsonValue["FunctionType"] = *property;
388f5c9f8bdSJason M. Bills                 }
389f5c9f8bdSJason M. Bills 
3908d78b7a9SPatrick Williams                 if (std::string* property = std::get_if<std::string>(
3917e860f15SJohn Edward Broadbent                         &pcieDevProperties["Function" + function +
3927e860f15SJohn Edward Broadbent                                            "DeviceClass"]);
393f5c9f8bdSJason M. Bills                     property)
394f5c9f8bdSJason M. Bills                 {
395f5c9f8bdSJason M. Bills                     asyncResp->res.jsonValue["DeviceClass"] = *property;
396f5c9f8bdSJason M. Bills                 }
397f5c9f8bdSJason M. Bills 
3988d78b7a9SPatrick Williams                 if (std::string* property = std::get_if<std::string>(
3997e860f15SJohn Edward Broadbent                         &pcieDevProperties["Function" + function +
4007e860f15SJohn Edward Broadbent                                            "ClassCode"]);
401f5c9f8bdSJason M. Bills                     property)
402f5c9f8bdSJason M. Bills                 {
403f5c9f8bdSJason M. Bills                     asyncResp->res.jsonValue["ClassCode"] = *property;
404f5c9f8bdSJason M. Bills                 }
405f5c9f8bdSJason M. Bills 
4068d78b7a9SPatrick Williams                 if (std::string* property = std::get_if<std::string>(
4077e860f15SJohn Edward Broadbent                         &pcieDevProperties["Function" + function +
4087e860f15SJohn Edward Broadbent                                            "RevisionId"]);
409f5c9f8bdSJason M. Bills                     property)
410f5c9f8bdSJason M. Bills                 {
411f5c9f8bdSJason M. Bills                     asyncResp->res.jsonValue["RevisionId"] = *property;
412f5c9f8bdSJason M. Bills                 }
413f5c9f8bdSJason M. Bills 
4148d78b7a9SPatrick Williams                 if (std::string* property = std::get_if<std::string>(
4157e860f15SJohn Edward Broadbent                         &pcieDevProperties["Function" + function +
4167e860f15SJohn Edward Broadbent                                            "SubsystemId"]);
417f5c9f8bdSJason M. Bills                     property)
418f5c9f8bdSJason M. Bills                 {
419f5c9f8bdSJason M. Bills                     asyncResp->res.jsonValue["SubsystemId"] = *property;
420f5c9f8bdSJason M. Bills                 }
421f5c9f8bdSJason M. Bills 
4228d78b7a9SPatrick Williams                 if (std::string* property = std::get_if<std::string>(
423f5c9f8bdSJason M. Bills                         &pcieDevProperties["Function" + function +
424f5c9f8bdSJason M. Bills                                            "SubsystemVendorId"]);
425f5c9f8bdSJason M. Bills                     property)
426f5c9f8bdSJason M. Bills                 {
427f5c9f8bdSJason M. Bills                     asyncResp->res.jsonValue["SubsystemVendorId"] = *property;
428f5c9f8bdSJason M. Bills                 }
429f5c9f8bdSJason M. Bills             };
430f5c9f8bdSJason M. Bills             std::string escapedPath = std::string(pciePath) + "/" + device;
431f5c9f8bdSJason M. Bills             dbus::utility::escapePathForDbus(escapedPath);
432f5c9f8bdSJason M. Bills             crow::connections::systemBus->async_method_call(
433f5c9f8bdSJason M. Bills                 std::move(getPCIeDeviceCallback), pcieService, escapedPath,
4347e860f15SJohn Edward Broadbent                 "org.freedesktop.DBus.Properties", "GetAll",
4357e860f15SJohn Edward Broadbent                 pcieDeviceInterface);
4367e860f15SJohn Edward Broadbent         });
437f5c9f8bdSJason M. Bills }
438f5c9f8bdSJason M. Bills 
439f5c9f8bdSJason M. Bills } // namespace redfish
440