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> 21168e20c1SEd Tanous #include <dbus_utility.hpp> 2245ca1b86SEd Tanous #include <query.hpp> 23ed398213SEd Tanous #include <registries/privilege_registry.hpp> 24f5c9f8bdSJason M. Bills 25f5c9f8bdSJason M. Bills namespace redfish 26f5c9f8bdSJason M. Bills { 27f5c9f8bdSJason M. Bills 28f5c9f8bdSJason M. Bills static constexpr char const* pcieService = "xyz.openbmc_project.PCIe"; 29f5c9f8bdSJason M. Bills static constexpr char const* pciePath = "/xyz/openbmc_project/PCIe"; 30f5c9f8bdSJason M. Bills static constexpr char const* pcieDeviceInterface = 31f5c9f8bdSJason M. Bills "xyz.openbmc_project.PCIe.Device"; 32f5c9f8bdSJason M. Bills 33b5a76932SEd Tanous static inline void 348d1b46d7Szhanghch05 getPCIeDeviceList(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 35adbe192aSJason M. Bills const std::string& name) 36f5c9f8bdSJason M. Bills { 37b9d36b47SEd Tanous auto getPCIeMapCallback = 38b9d36b47SEd Tanous [asyncResp, name](const boost::system::error_code ec, 39b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreePathsResponse& 40b9d36b47SEd Tanous pcieDevicePaths) { 41f5c9f8bdSJason M. Bills if (ec) 42f5c9f8bdSJason M. Bills { 43a2730f01SAndrew Geissler BMCWEB_LOG_DEBUG << "no PCIe device paths found ec: " 44f5c9f8bdSJason M. Bills << ec.message(); 45a2730f01SAndrew Geissler // Not an error, system just doesn't have PCIe info 46f5c9f8bdSJason M. Bills return; 47f5c9f8bdSJason M. Bills } 48adbe192aSJason M. Bills nlohmann::json& pcieDeviceList = asyncResp->res.jsonValue[name]; 49f5c9f8bdSJason M. Bills pcieDeviceList = nlohmann::json::array(); 50f5c9f8bdSJason M. Bills for (const std::string& pcieDevicePath : pcieDevicePaths) 51f5c9f8bdSJason M. Bills { 523174e4dfSEd Tanous size_t devStart = pcieDevicePath.rfind('/'); 53f5c9f8bdSJason M. Bills if (devStart == std::string::npos) 54f5c9f8bdSJason M. Bills { 55f5c9f8bdSJason M. Bills continue; 56f5c9f8bdSJason M. Bills } 57f5c9f8bdSJason M. Bills 58f5c9f8bdSJason M. Bills std::string devName = pcieDevicePath.substr(devStart + 1); 59f5c9f8bdSJason M. Bills if (devName.empty()) 60f5c9f8bdSJason M. Bills { 61f5c9f8bdSJason M. Bills continue; 62f5c9f8bdSJason M. Bills } 631476687dSEd Tanous nlohmann::json::object_t pcieDevice; 641476687dSEd Tanous pcieDevice["@odata.id"] = 651476687dSEd Tanous "/redfish/v1/Systems/system/PCIeDevices/" + devName; 661476687dSEd Tanous pcieDeviceList.push_back(std::move(pcieDevice)); 67f5c9f8bdSJason M. Bills } 68*002d39b4SEd Tanous asyncResp->res.jsonValue[name + "@odata.count"] = pcieDeviceList.size(); 69f5c9f8bdSJason M. Bills }; 70f5c9f8bdSJason M. Bills crow::connections::systemBus->async_method_call( 71f5c9f8bdSJason M. Bills std::move(getPCIeMapCallback), "xyz.openbmc_project.ObjectMapper", 72f5c9f8bdSJason M. Bills "/xyz/openbmc_project/object_mapper", 73f5c9f8bdSJason M. Bills "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", 74f5c9f8bdSJason M. Bills std::string(pciePath) + "/", 1, std::array<std::string, 0>()); 75f5c9f8bdSJason M. Bills } 76f5c9f8bdSJason M. Bills 777e860f15SJohn Edward Broadbent inline void requestRoutesSystemPCIeDeviceCollection(App& app) 78adbe192aSJason M. Bills { 79adbe192aSJason M. Bills /** 80adbe192aSJason M. Bills * Functions triggers appropriate requests on DBus 81adbe192aSJason M. Bills */ 827e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/PCIeDevices/") 83ed398213SEd Tanous .privileges(redfish::privileges::getPCIeDeviceCollection) 847e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 8545ca1b86SEd Tanous [&app](const crow::Request& req, 8645ca1b86SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 8745ca1b86SEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp->res)) 88adbe192aSJason M. Bills { 8945ca1b86SEd Tanous return; 9045ca1b86SEd Tanous } 911476687dSEd Tanous 921476687dSEd Tanous asyncResp->res.jsonValue["@odata.type"] = 931476687dSEd Tanous "#PCIeDeviceCollection.PCIeDeviceCollection"; 941476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = 951476687dSEd Tanous "/redfish/v1/Systems/system/PCIeDevices"; 961476687dSEd Tanous asyncResp->res.jsonValue["Name"] = "PCIe Device Collection"; 97*002d39b4SEd Tanous asyncResp->res.jsonValue["Description"] = "Collection of PCIe Devices"; 981476687dSEd Tanous asyncResp->res.jsonValue["Members"] = nlohmann::json::array(); 991476687dSEd Tanous asyncResp->res.jsonValue["Members@odata.count"] = 0; 100adbe192aSJason M. Bills getPCIeDeviceList(asyncResp, "Members"); 1017e860f15SJohn Edward Broadbent }); 102f5c9f8bdSJason M. Bills } 103f5c9f8bdSJason M. Bills 10462cd45afSSpencer Ku inline std::optional<std::string> 10562cd45afSSpencer Ku redfishPcieGenerationFromDbus(const std::string& generationInUse) 10662cd45afSSpencer Ku { 10762cd45afSSpencer Ku if (generationInUse == 10862cd45afSSpencer Ku "xyz.openbmc_project.Inventory.Item.PCIeSlot.Generations.Gen1") 10962cd45afSSpencer Ku { 11062cd45afSSpencer Ku return "Gen1"; 11162cd45afSSpencer Ku } 11262cd45afSSpencer Ku if (generationInUse == 11362cd45afSSpencer Ku "xyz.openbmc_project.Inventory.Item.PCIeSlot.Generations.Gen2") 11462cd45afSSpencer Ku { 11562cd45afSSpencer Ku return "Gen2"; 11662cd45afSSpencer Ku } 11762cd45afSSpencer Ku if (generationInUse == 11862cd45afSSpencer Ku "xyz.openbmc_project.Inventory.Item.PCIeSlot.Generations.Gen3") 11962cd45afSSpencer Ku { 12062cd45afSSpencer Ku return "Gen3"; 12162cd45afSSpencer Ku } 12262cd45afSSpencer Ku if (generationInUse == 12362cd45afSSpencer Ku "xyz.openbmc_project.Inventory.Item.PCIeSlot.Generations.Gen4") 12462cd45afSSpencer Ku { 12562cd45afSSpencer Ku return "Gen4"; 12662cd45afSSpencer Ku } 12762cd45afSSpencer Ku if (generationInUse == 12862cd45afSSpencer Ku "xyz.openbmc_project.Inventory.Item.PCIeSlot.Generations.Gen5") 12962cd45afSSpencer Ku { 13062cd45afSSpencer Ku return "Gen5"; 13162cd45afSSpencer Ku } 13262cd45afSSpencer Ku if (generationInUse.empty() || 13362cd45afSSpencer Ku generationInUse == 13462cd45afSSpencer Ku "xyz.openbmc_project.Inventory.Item.PCIeSlot.Generations.Unknown") 13562cd45afSSpencer Ku { 13662cd45afSSpencer Ku return ""; 13762cd45afSSpencer Ku } 13862cd45afSSpencer Ku 13962cd45afSSpencer Ku // The value is not unknown or Gen1-5, need return an internal error. 14062cd45afSSpencer Ku return std::nullopt; 14162cd45afSSpencer Ku } 14262cd45afSSpencer Ku 1437e860f15SJohn Edward Broadbent inline void requestRoutesSystemPCIeDevice(App& app) 144f5c9f8bdSJason M. Bills { 1457e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/PCIeDevices/<str>/") 146ed398213SEd Tanous .privileges(redfish::privileges::getPCIeDevice) 147*002d39b4SEd Tanous .methods(boost::beast::http::verb::get)( 148*002d39b4SEd Tanous [&app](const crow::Request& req, 1497e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 15045ca1b86SEd Tanous const std::string& device) { 15145ca1b86SEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp->res)) 1527e860f15SJohn Edward Broadbent { 15345ca1b86SEd Tanous return; 15445ca1b86SEd Tanous } 155168e20c1SEd Tanous auto getPCIeDeviceCallback = 15645ca1b86SEd Tanous [asyncResp, device]( 15745ca1b86SEd Tanous const boost::system::error_code ec, 15845ca1b86SEd Tanous const dbus::utility::DBusPropertiesMap& pcieDevProperties) { 159f5c9f8bdSJason M. Bills if (ec) 160f5c9f8bdSJason M. Bills { 161f5c9f8bdSJason M. Bills BMCWEB_LOG_DEBUG 162*002d39b4SEd Tanous << "failed to get PCIe Device properties ec: " << ec.value() 163*002d39b4SEd Tanous << ": " << ec.message(); 16445ca1b86SEd Tanous if (ec.value() == 16545ca1b86SEd Tanous boost::system::linux_error::bad_request_descriptor) 166f5c9f8bdSJason M. Bills { 167*002d39b4SEd Tanous messages::resourceNotFound(asyncResp->res, "PCIeDevice", 168*002d39b4SEd Tanous device); 169f5c9f8bdSJason M. Bills } 170f5c9f8bdSJason M. Bills else 171f5c9f8bdSJason M. Bills { 172f5c9f8bdSJason M. Bills messages::internalError(asyncResp->res); 173f5c9f8bdSJason M. Bills } 174f5c9f8bdSJason M. Bills return; 175f5c9f8bdSJason M. Bills } 176f5c9f8bdSJason M. Bills 1771476687dSEd Tanous asyncResp->res.jsonValue["@odata.type"] = 1781476687dSEd Tanous "#PCIeDevice.v1_4_0.PCIeDevice"; 1791476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = 1801476687dSEd Tanous "/redfish/v1/Systems/system/PCIeDevices/" + device; 1811476687dSEd Tanous asyncResp->res.jsonValue["Name"] = "PCIe Device"; 1821476687dSEd Tanous asyncResp->res.jsonValue["Id"] = device; 1831476687dSEd Tanous 1841476687dSEd Tanous asyncResp->res.jsonValue["PCIeFunctions"]["@odata.id"] = 18545ca1b86SEd Tanous "/redfish/v1/Systems/system/PCIeDevices/" + device + 1861476687dSEd Tanous "/PCIeFunctions"; 187b9d36b47SEd Tanous for (const auto& property : pcieDevProperties) 188f5c9f8bdSJason M. Bills { 189b9d36b47SEd Tanous const std::string* propertyString = 190b9d36b47SEd Tanous std::get_if<std::string>(&property.second); 191b9d36b47SEd Tanous if (property.first == "Manufacturer") 192b9d36b47SEd Tanous { 193b9d36b47SEd Tanous if (propertyString == nullptr) 194b9d36b47SEd Tanous { 195b9d36b47SEd Tanous messages::internalError(asyncResp->res); 196b9d36b47SEd Tanous return; 197b9d36b47SEd Tanous } 198*002d39b4SEd Tanous asyncResp->res.jsonValue["Manufacturer"] = *propertyString; 199168e20c1SEd Tanous } 200b9d36b47SEd Tanous if (property.first == "DeviceType") 201168e20c1SEd Tanous { 202b9d36b47SEd Tanous if (propertyString == nullptr) 203b9d36b47SEd Tanous { 204b9d36b47SEd Tanous messages::internalError(asyncResp->res); 205b9d36b47SEd Tanous return; 206168e20c1SEd Tanous } 207*002d39b4SEd Tanous asyncResp->res.jsonValue["DeviceType"] = *propertyString; 208f5c9f8bdSJason M. Bills } 209b9d36b47SEd Tanous if (property.first == "GenerationInUse") 21062cd45afSSpencer Ku { 211b9d36b47SEd Tanous if (propertyString == nullptr) 212b9d36b47SEd Tanous { 213b9d36b47SEd Tanous messages::internalError(asyncResp->res); 214b9d36b47SEd Tanous return; 215b9d36b47SEd Tanous } 21662cd45afSSpencer Ku std::optional<std::string> generationInUse = 21745ca1b86SEd Tanous redfishPcieGenerationFromDbus(*propertyString); 21862cd45afSSpencer Ku if (!generationInUse) 21962cd45afSSpencer Ku { 22062cd45afSSpencer Ku messages::internalError(asyncResp->res); 22162cd45afSSpencer Ku return; 22262cd45afSSpencer Ku } 22326f6976fSEd Tanous if (generationInUse->empty()) 22462cd45afSSpencer Ku { 22562cd45afSSpencer Ku // unknown, no need to handle 22662cd45afSSpencer Ku return; 22762cd45afSSpencer Ku } 228*002d39b4SEd Tanous asyncResp->res.jsonValue["PCIeInterface"]["PCIeType"] = 22962cd45afSSpencer Ku *generationInUse; 23062cd45afSSpencer Ku } 231b9d36b47SEd Tanous } 232dede6a98SJason M. Bills }; 233dede6a98SJason M. Bills std::string escapedPath = std::string(pciePath) + "/" + device; 234dede6a98SJason M. Bills dbus::utility::escapePathForDbus(escapedPath); 235dede6a98SJason M. Bills crow::connections::systemBus->async_method_call( 236dede6a98SJason M. Bills std::move(getPCIeDeviceCallback), pcieService, escapedPath, 237*002d39b4SEd Tanous "org.freedesktop.DBus.Properties", "GetAll", pcieDeviceInterface); 2387e860f15SJohn Edward Broadbent }); 239dede6a98SJason M. Bills } 240dede6a98SJason M. Bills 2417e860f15SJohn Edward Broadbent inline void requestRoutesSystemPCIeFunctionCollection(App& app) 2427e860f15SJohn Edward Broadbent { 243dede6a98SJason M. Bills /** 244dede6a98SJason M. Bills * Functions triggers appropriate requests on DBus 245dede6a98SJason M. Bills */ 2467e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, 2477e860f15SJohn Edward Broadbent "/redfish/v1/Systems/system/PCIeDevices/<str>/PCIeFunctions/") 248ed398213SEd Tanous .privileges(redfish::privileges::getPCIeFunctionCollection) 249*002d39b4SEd Tanous .methods(boost::beast::http::verb::get)( 250*002d39b4SEd Tanous [&app](const crow::Request& req, 2517e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 25245ca1b86SEd Tanous const std::string& device) { 25345ca1b86SEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp->res)) 254dede6a98SJason M. Bills { 25545ca1b86SEd Tanous return; 25645ca1b86SEd Tanous } 2571476687dSEd Tanous 2581476687dSEd Tanous asyncResp->res.jsonValue["@odata.type"] = 2591476687dSEd Tanous "#PCIeFunctionCollection.PCIeFunctionCollection"; 2601476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = 2611476687dSEd Tanous "/redfish/v1/Systems/system/PCIeDevices/" + device + 2621476687dSEd Tanous "/PCIeFunctions"; 2631476687dSEd Tanous asyncResp->res.jsonValue["Name"] = "PCIe Function Collection"; 2641476687dSEd Tanous asyncResp->res.jsonValue["Description"] = 2651476687dSEd Tanous "Collection of PCIe Functions for PCIe Device " + device; 266dede6a98SJason M. Bills 267b9d36b47SEd Tanous auto getPCIeDeviceCallback = 26845ca1b86SEd Tanous [asyncResp, device]( 26945ca1b86SEd Tanous const boost::system::error_code ec, 27045ca1b86SEd Tanous const dbus::utility::DBusPropertiesMap& pcieDevProperties) { 2717e860f15SJohn Edward Broadbent if (ec) 2727e860f15SJohn Edward Broadbent { 2737e860f15SJohn Edward Broadbent BMCWEB_LOG_DEBUG 274*002d39b4SEd Tanous << "failed to get PCIe Device properties ec: " << ec.value() 275*002d39b4SEd Tanous << ": " << ec.message(); 27645ca1b86SEd Tanous if (ec.value() == 27745ca1b86SEd Tanous boost::system::linux_error::bad_request_descriptor) 2787e860f15SJohn Edward Broadbent { 279*002d39b4SEd Tanous messages::resourceNotFound(asyncResp->res, "PCIeDevice", 280*002d39b4SEd Tanous device); 2817e860f15SJohn Edward Broadbent } 2827e860f15SJohn Edward Broadbent else 2837e860f15SJohn Edward Broadbent { 2847e860f15SJohn Edward Broadbent messages::internalError(asyncResp->res); 2857e860f15SJohn Edward Broadbent } 2867e860f15SJohn Edward Broadbent return; 2877e860f15SJohn Edward Broadbent } 2887e860f15SJohn Edward Broadbent 2897e860f15SJohn Edward Broadbent nlohmann::json& pcieFunctionList = 2907e860f15SJohn Edward Broadbent asyncResp->res.jsonValue["Members"]; 2917e860f15SJohn Edward Broadbent pcieFunctionList = nlohmann::json::array(); 2927e860f15SJohn Edward Broadbent static constexpr const int maxPciFunctionNum = 8; 29345ca1b86SEd Tanous for (int functionNum = 0; functionNum < maxPciFunctionNum; 29445ca1b86SEd Tanous functionNum++) 2957e860f15SJohn Edward Broadbent { 296b9d36b47SEd Tanous // Check if this function exists by looking for a 297b9d36b47SEd Tanous // device ID 2987e860f15SJohn Edward Broadbent std::string devIDProperty = 299*002d39b4SEd Tanous "Function" + std::to_string(functionNum) + "DeviceId"; 300b9d36b47SEd Tanous const std::string* property = nullptr; 301b9d36b47SEd Tanous for (const auto& propEntry : pcieDevProperties) 3027e860f15SJohn Edward Broadbent { 303b9d36b47SEd Tanous if (propEntry.first == devIDProperty) 304b9d36b47SEd Tanous { 305*002d39b4SEd Tanous property = std::get_if<std::string>(&propEntry.second); 306b9d36b47SEd Tanous } 307b9d36b47SEd Tanous } 308b9d36b47SEd Tanous if (property == nullptr || !property->empty()) 309b9d36b47SEd Tanous { 310b9d36b47SEd Tanous return; 311b9d36b47SEd Tanous } 3121476687dSEd Tanous nlohmann::json::object_t pcieFunction; 3131476687dSEd Tanous pcieFunction["@odata.id"] = 3141476687dSEd Tanous "/redfish/v1/Systems/system/PCIeDevices/" + device + 3151476687dSEd Tanous "/PCIeFunctions/" + std::to_string(functionNum); 3161476687dSEd Tanous pcieFunctionList.push_back(std::move(pcieFunction)); 3177e860f15SJohn Edward Broadbent } 318a818d15aSJiaqing Zhao asyncResp->res.jsonValue["Members@odata.count"] = 3197e860f15SJohn Edward Broadbent pcieFunctionList.size(); 3207e860f15SJohn Edward Broadbent }; 3217e860f15SJohn Edward Broadbent std::string escapedPath = std::string(pciePath) + "/" + device; 3227e860f15SJohn Edward Broadbent dbus::utility::escapePathForDbus(escapedPath); 3237e860f15SJohn Edward Broadbent crow::connections::systemBus->async_method_call( 3247e860f15SJohn Edward Broadbent std::move(getPCIeDeviceCallback), pcieService, escapedPath, 325*002d39b4SEd Tanous "org.freedesktop.DBus.Properties", "GetAll", pcieDeviceInterface); 3267e860f15SJohn Edward Broadbent }); 3277e860f15SJohn Edward Broadbent } 3287e860f15SJohn Edward Broadbent 3297e860f15SJohn Edward Broadbent inline void requestRoutesSystemPCIeFunction(App& app) 3307e860f15SJohn Edward Broadbent { 3317e860f15SJohn Edward Broadbent BMCWEB_ROUTE( 3327e860f15SJohn Edward Broadbent app, 3337e860f15SJohn Edward Broadbent "/redfish/v1/Systems/system/PCIeDevices/<str>/PCIeFunctions/<str>/") 334ed398213SEd Tanous .privileges(redfish::privileges::getPCIeFunction) 335*002d39b4SEd Tanous .methods(boost::beast::http::verb::get)( 336*002d39b4SEd Tanous [&app](const crow::Request& req, 33745ca1b86SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 338*002d39b4SEd Tanous const std::string& device, const std::string& function) { 33945ca1b86SEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp->res)) 34045ca1b86SEd Tanous { 34145ca1b86SEd Tanous return; 34245ca1b86SEd Tanous } 343168e20c1SEd Tanous auto getPCIeDeviceCallback = 344168e20c1SEd Tanous [asyncResp, device, function]( 3457e860f15SJohn Edward Broadbent const boost::system::error_code ec, 346b9d36b47SEd Tanous const dbus::utility::DBusPropertiesMap& pcieDevProperties) { 347dede6a98SJason M. Bills if (ec) 348dede6a98SJason M. Bills { 349dede6a98SJason M. Bills BMCWEB_LOG_DEBUG 350*002d39b4SEd Tanous << "failed to get PCIe Device properties ec: " << ec.value() 351*002d39b4SEd Tanous << ": " << ec.message(); 352dede6a98SJason M. Bills if (ec.value() == 353dede6a98SJason M. Bills boost::system::linux_error::bad_request_descriptor) 354dede6a98SJason M. Bills { 355*002d39b4SEd Tanous messages::resourceNotFound(asyncResp->res, "PCIeDevice", 356*002d39b4SEd Tanous device); 357dede6a98SJason M. Bills } 358dede6a98SJason M. Bills else 359dede6a98SJason M. Bills { 360dede6a98SJason M. Bills messages::internalError(asyncResp->res); 361dede6a98SJason M. Bills } 362dede6a98SJason M. Bills return; 363dede6a98SJason M. Bills } 364dede6a98SJason M. Bills 3651476687dSEd Tanous // Check if this function exists by looking for a device 3661476687dSEd Tanous // ID 367b9d36b47SEd Tanous std::string functionName = "Function" + function; 368b9d36b47SEd Tanous std::string devIDProperty = functionName + "DeviceId"; 369b9d36b47SEd Tanous 370b9d36b47SEd Tanous const std::string* devIdProperty = nullptr; 371b9d36b47SEd Tanous for (const auto& property : pcieDevProperties) 372b9d36b47SEd Tanous { 373b9d36b47SEd Tanous if (property.first == devIDProperty) 374b9d36b47SEd Tanous { 375*002d39b4SEd Tanous devIdProperty = std::get_if<std::string>(&property.second); 376b9d36b47SEd Tanous continue; 377b9d36b47SEd Tanous } 378b9d36b47SEd Tanous } 379b9d36b47SEd Tanous if (devIdProperty == nullptr || !devIdProperty->empty()) 380f5c9f8bdSJason M. Bills { 381*002d39b4SEd Tanous messages::resourceNotFound(asyncResp->res, "PCIeFunction", 382*002d39b4SEd Tanous function); 383f5c9f8bdSJason M. Bills return; 384f5c9f8bdSJason M. Bills } 385f5c9f8bdSJason M. Bills 3861476687dSEd Tanous asyncResp->res.jsonValue["@odata.type"] = 3871476687dSEd Tanous "#PCIeFunction.v1_2_0.PCIeFunction"; 3881476687dSEd Tanous asyncResp->res.jsonValue["@odata.id"] = 389168e20c1SEd Tanous "/redfish/v1/Systems/system/PCIeDevices/" + device + 3901476687dSEd Tanous "/PCIeFunctions/" + function; 3911476687dSEd Tanous asyncResp->res.jsonValue["Name"] = "PCIe Function"; 3921476687dSEd Tanous asyncResp->res.jsonValue["Id"] = function; 393*002d39b4SEd Tanous asyncResp->res.jsonValue["FunctionId"] = std::stoi(function); 394*002d39b4SEd Tanous asyncResp->res.jsonValue["Links"]["PCIeDevice"]["@odata.id"] = 3951476687dSEd Tanous "/redfish/v1/Systems/system/PCIeDevices/" + device; 396f5c9f8bdSJason M. Bills 397b9d36b47SEd Tanous for (const auto& property : pcieDevProperties) 398f5c9f8bdSJason M. Bills { 399b9d36b47SEd Tanous const std::string* strProperty = 400b9d36b47SEd Tanous std::get_if<std::string>(&property.second); 401b9d36b47SEd Tanous if (property.first == functionName + "DeviceId") 402f5c9f8bdSJason M. Bills { 403b9d36b47SEd Tanous asyncResp->res.jsonValue["DeviceId"] = *strProperty; 404f5c9f8bdSJason M. Bills } 405b9d36b47SEd Tanous if (property.first == functionName + "VendorId") 406f5c9f8bdSJason M. Bills { 407b9d36b47SEd Tanous asyncResp->res.jsonValue["VendorId"] = *strProperty; 408f5c9f8bdSJason M. Bills } 409b9d36b47SEd Tanous if (property.first == functionName + "FunctionType") 410f5c9f8bdSJason M. Bills { 411*002d39b4SEd Tanous asyncResp->res.jsonValue["FunctionType"] = *strProperty; 412f5c9f8bdSJason M. Bills } 413b9d36b47SEd Tanous if (property.first == functionName + "DeviceClass") 414f5c9f8bdSJason M. Bills { 415*002d39b4SEd Tanous asyncResp->res.jsonValue["DeviceClass"] = *strProperty; 416f5c9f8bdSJason M. Bills } 417b9d36b47SEd Tanous if (property.first == functionName + "ClassCode") 418f5c9f8bdSJason M. Bills { 419*002d39b4SEd Tanous asyncResp->res.jsonValue["ClassCode"] = *strProperty; 420f5c9f8bdSJason M. Bills } 421b9d36b47SEd Tanous if (property.first == functionName + "RevisionId") 422f5c9f8bdSJason M. Bills { 423*002d39b4SEd Tanous asyncResp->res.jsonValue["RevisionId"] = *strProperty; 424f5c9f8bdSJason M. Bills } 425b9d36b47SEd Tanous if (property.first == functionName + "SubsystemId") 426b9d36b47SEd Tanous { 427*002d39b4SEd Tanous asyncResp->res.jsonValue["SubsystemId"] = *strProperty; 428b9d36b47SEd Tanous } 429*002d39b4SEd Tanous if (property.first == functionName + "SubsystemVendorId") 430f5c9f8bdSJason M. Bills { 431168e20c1SEd Tanous asyncResp->res.jsonValue["SubsystemVendorId"] = 432b9d36b47SEd Tanous *strProperty; 433b9d36b47SEd Tanous } 434f5c9f8bdSJason M. Bills } 435f5c9f8bdSJason M. Bills }; 436f5c9f8bdSJason M. Bills std::string escapedPath = std::string(pciePath) + "/" + device; 437f5c9f8bdSJason M. Bills dbus::utility::escapePathForDbus(escapedPath); 438f5c9f8bdSJason M. Bills crow::connections::systemBus->async_method_call( 439f5c9f8bdSJason M. Bills std::move(getPCIeDeviceCallback), pcieService, escapedPath, 440*002d39b4SEd Tanous "org.freedesktop.DBus.Properties", "GetAll", pcieDeviceInterface); 4417e860f15SJohn Edward Broadbent }); 442f5c9f8bdSJason M. Bills } 443f5c9f8bdSJason M. Bills 444f5c9f8bdSJason M. Bills } // namespace redfish 445