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