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> 22ed398213SEd Tanous #include <registries/privilege_registry.hpp> 23f5c9f8bdSJason M. Bills 24f5c9f8bdSJason M. Bills namespace redfish 25f5c9f8bdSJason M. Bills { 26f5c9f8bdSJason M. Bills 27f5c9f8bdSJason M. Bills static constexpr char const* pcieService = "xyz.openbmc_project.PCIe"; 28f5c9f8bdSJason M. Bills static constexpr char const* pciePath = "/xyz/openbmc_project/PCIe"; 29f5c9f8bdSJason M. Bills static constexpr char const* pcieDeviceInterface = 30f5c9f8bdSJason M. Bills "xyz.openbmc_project.PCIe.Device"; 31f5c9f8bdSJason M. Bills 32b5a76932SEd Tanous static inline void 338d1b46d7Szhanghch05 getPCIeDeviceList(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 34adbe192aSJason M. Bills const std::string& name) 35f5c9f8bdSJason M. Bills { 36adbe192aSJason M. Bills auto getPCIeMapCallback = [asyncResp, name]( 37adbe192aSJason M. Bills const boost::system::error_code ec, 38f5c9f8bdSJason M. Bills std::vector<std::string>& pcieDevicePaths) { 39f5c9f8bdSJason M. Bills if (ec) 40f5c9f8bdSJason M. Bills { 41a2730f01SAndrew Geissler BMCWEB_LOG_DEBUG << "no PCIe device paths found ec: " 42f5c9f8bdSJason M. Bills << ec.message(); 43a2730f01SAndrew Geissler // Not an error, system just doesn't have PCIe info 44f5c9f8bdSJason M. Bills return; 45f5c9f8bdSJason M. Bills } 46adbe192aSJason M. Bills nlohmann::json& pcieDeviceList = asyncResp->res.jsonValue[name]; 47f5c9f8bdSJason M. Bills pcieDeviceList = nlohmann::json::array(); 48f5c9f8bdSJason M. Bills for (const std::string& pcieDevicePath : pcieDevicePaths) 49f5c9f8bdSJason M. Bills { 503174e4dfSEd Tanous size_t devStart = pcieDevicePath.rfind('/'); 51f5c9f8bdSJason M. Bills if (devStart == std::string::npos) 52f5c9f8bdSJason M. Bills { 53f5c9f8bdSJason M. Bills continue; 54f5c9f8bdSJason M. Bills } 55f5c9f8bdSJason M. Bills 56f5c9f8bdSJason M. Bills std::string devName = pcieDevicePath.substr(devStart + 1); 57f5c9f8bdSJason M. Bills if (devName.empty()) 58f5c9f8bdSJason M. Bills { 59f5c9f8bdSJason M. Bills continue; 60f5c9f8bdSJason M. Bills } 61f5c9f8bdSJason M. Bills pcieDeviceList.push_back( 62f5c9f8bdSJason M. Bills {{"@odata.id", 63f5c9f8bdSJason M. Bills "/redfish/v1/Systems/system/PCIeDevices/" + devName}}); 64f5c9f8bdSJason M. Bills } 65adbe192aSJason M. Bills asyncResp->res.jsonValue[name + "@odata.count"] = pcieDeviceList.size(); 66f5c9f8bdSJason M. Bills }; 67f5c9f8bdSJason M. Bills crow::connections::systemBus->async_method_call( 68f5c9f8bdSJason M. Bills std::move(getPCIeMapCallback), "xyz.openbmc_project.ObjectMapper", 69f5c9f8bdSJason M. Bills "/xyz/openbmc_project/object_mapper", 70f5c9f8bdSJason M. Bills "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", 71f5c9f8bdSJason M. Bills std::string(pciePath) + "/", 1, std::array<std::string, 0>()); 72f5c9f8bdSJason M. Bills } 73f5c9f8bdSJason M. Bills 747e860f15SJohn Edward Broadbent inline void requestRoutesSystemPCIeDeviceCollection(App& app) 75adbe192aSJason M. Bills { 76adbe192aSJason M. Bills /** 77adbe192aSJason M. Bills * Functions triggers appropriate requests on DBus 78adbe192aSJason M. Bills */ 797e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/PCIeDevices/") 80ed398213SEd Tanous .privileges(redfish::privileges::getPCIeDeviceCollection) 817e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 827e860f15SJohn Edward Broadbent [](const crow::Request&, 837e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 847e860f15SJohn Edward Broadbent 85adbe192aSJason M. Bills { 86adbe192aSJason M. Bills asyncResp->res.jsonValue = { 877e860f15SJohn Edward Broadbent {"@odata.type", 887e860f15SJohn Edward Broadbent "#PCIeDeviceCollection.PCIeDeviceCollection"}, 89adbe192aSJason M. Bills {"@odata.id", "/redfish/v1/Systems/system/PCIeDevices"}, 90adbe192aSJason M. Bills {"Name", "PCIe Device Collection"}, 91adbe192aSJason M. Bills {"Description", "Collection of PCIe Devices"}, 92adbe192aSJason M. Bills {"Members", nlohmann::json::array()}, 93adbe192aSJason M. Bills {"Members@odata.count", 0}}; 94adbe192aSJason M. Bills getPCIeDeviceList(asyncResp, "Members"); 957e860f15SJohn Edward Broadbent }); 96f5c9f8bdSJason M. Bills } 97f5c9f8bdSJason M. Bills 9862cd45afSSpencer Ku inline std::optional<std::string> 9962cd45afSSpencer Ku redfishPcieGenerationFromDbus(const std::string& generationInUse) 10062cd45afSSpencer Ku { 10162cd45afSSpencer Ku if (generationInUse == 10262cd45afSSpencer Ku "xyz.openbmc_project.Inventory.Item.PCIeSlot.Generations.Gen1") 10362cd45afSSpencer Ku { 10462cd45afSSpencer Ku return "Gen1"; 10562cd45afSSpencer Ku } 10662cd45afSSpencer Ku if (generationInUse == 10762cd45afSSpencer Ku "xyz.openbmc_project.Inventory.Item.PCIeSlot.Generations.Gen2") 10862cd45afSSpencer Ku { 10962cd45afSSpencer Ku return "Gen2"; 11062cd45afSSpencer Ku } 11162cd45afSSpencer Ku if (generationInUse == 11262cd45afSSpencer Ku "xyz.openbmc_project.Inventory.Item.PCIeSlot.Generations.Gen3") 11362cd45afSSpencer Ku { 11462cd45afSSpencer Ku return "Gen3"; 11562cd45afSSpencer Ku } 11662cd45afSSpencer Ku if (generationInUse == 11762cd45afSSpencer Ku "xyz.openbmc_project.Inventory.Item.PCIeSlot.Generations.Gen4") 11862cd45afSSpencer Ku { 11962cd45afSSpencer Ku return "Gen4"; 12062cd45afSSpencer Ku } 12162cd45afSSpencer Ku if (generationInUse == 12262cd45afSSpencer Ku "xyz.openbmc_project.Inventory.Item.PCIeSlot.Generations.Gen5") 12362cd45afSSpencer Ku { 12462cd45afSSpencer Ku return "Gen5"; 12562cd45afSSpencer Ku } 12662cd45afSSpencer Ku if (generationInUse.empty() || 12762cd45afSSpencer Ku generationInUse == 12862cd45afSSpencer Ku "xyz.openbmc_project.Inventory.Item.PCIeSlot.Generations.Unknown") 12962cd45afSSpencer Ku { 13062cd45afSSpencer Ku return ""; 13162cd45afSSpencer Ku } 13262cd45afSSpencer Ku 13362cd45afSSpencer Ku // The value is not unknown or Gen1-5, need return an internal error. 13462cd45afSSpencer Ku return std::nullopt; 13562cd45afSSpencer Ku } 13662cd45afSSpencer Ku 1377e860f15SJohn Edward Broadbent inline void requestRoutesSystemPCIeDevice(App& app) 138f5c9f8bdSJason M. Bills { 1397e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/PCIeDevices/<str>/") 140ed398213SEd Tanous .privileges(redfish::privileges::getPCIeDevice) 1417e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 1427e860f15SJohn Edward Broadbent [](const crow::Request&, 1437e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1447e860f15SJohn Edward Broadbent const std::string& device) 145f5c9f8bdSJason M. Bills 1467e860f15SJohn Edward Broadbent { 147168e20c1SEd Tanous auto getPCIeDeviceCallback = 148168e20c1SEd Tanous [asyncResp, 149168e20c1SEd Tanous device](const boost::system::error_code ec, 1507e860f15SJohn Edward Broadbent boost::container::flat_map< 151168e20c1SEd Tanous std::string, dbus::utility::DbusVariantType>& 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(); 158168e20c1SEd Tanous if (ec.value() == boost::system::linux_error:: 159168e20c1SEd Tanous bad_request_descriptor) 160f5c9f8bdSJason M. Bills { 161168e20c1SEd Tanous messages::resourceNotFound( 162168e20c1SEd Tanous asyncResp->res, "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", 174168e20c1SEd Tanous "/redfish/v1/Systems/system/PCIeDevices/" + 175168e20c1SEd Tanous device}, 176f5c9f8bdSJason M. Bills {"Name", "PCIe Device"}, 177f5c9f8bdSJason M. Bills {"Id", device}}; 178f5c9f8bdSJason M. Bills 1798d78b7a9SPatrick Williams if (std::string* property = std::get_if<std::string>( 180f5c9f8bdSJason M. Bills &pcieDevProperties["Manufacturer"]); 181f5c9f8bdSJason M. Bills property) 182f5c9f8bdSJason M. Bills { 183168e20c1SEd Tanous asyncResp->res.jsonValue["Manufacturer"] = 184168e20c1SEd Tanous *property; 185168e20c1SEd Tanous } 186168e20c1SEd Tanous 187168e20c1SEd Tanous if (std::string* property = std::get_if<std::string>( 188168e20c1SEd Tanous &pcieDevProperties["DeviceType"]); 189168e20c1SEd Tanous property) 190168e20c1SEd Tanous { 191168e20c1SEd Tanous asyncResp->res.jsonValue["DeviceType"] = *property; 192168e20c1SEd Tanous } 193168e20c1SEd Tanous 194168e20c1SEd Tanous if (std::string* property = std::get_if<std::string>( 195168e20c1SEd Tanous &pcieDevProperties["Manufacturer"]); 196168e20c1SEd Tanous property) 197168e20c1SEd Tanous { 198168e20c1SEd Tanous asyncResp->res.jsonValue["Manufacturer"] = 199168e20c1SEd Tanous *property; 200f5c9f8bdSJason M. Bills } 201f5c9f8bdSJason M. Bills 2028d78b7a9SPatrick Williams if (std::string* property = std::get_if<std::string>( 203f5c9f8bdSJason M. Bills &pcieDevProperties["DeviceType"]); 204f5c9f8bdSJason M. Bills property) 205f5c9f8bdSJason M. Bills { 206f5c9f8bdSJason M. Bills asyncResp->res.jsonValue["DeviceType"] = *property; 207f5c9f8bdSJason M. Bills } 208f5c9f8bdSJason M. Bills 20962cd45afSSpencer Ku if (std::string* property = std::get_if<std::string>( 21062cd45afSSpencer Ku &pcieDevProperties["GenerationInUse"]); 21162cd45afSSpencer Ku property) 21262cd45afSSpencer Ku { 21362cd45afSSpencer Ku std::optional<std::string> generationInUse = 21462cd45afSSpencer Ku redfishPcieGenerationFromDbus(*property); 21562cd45afSSpencer Ku if (!generationInUse) 21662cd45afSSpencer Ku { 21762cd45afSSpencer Ku messages::internalError(asyncResp->res); 21862cd45afSSpencer Ku return; 21962cd45afSSpencer Ku } 22062cd45afSSpencer Ku if (*generationInUse == "") 22162cd45afSSpencer Ku { 22262cd45afSSpencer Ku // unknown, no need to handle 22362cd45afSSpencer Ku return; 22462cd45afSSpencer Ku } 225168e20c1SEd Tanous asyncResp->res 226168e20c1SEd Tanous .jsonValue["PCIeInterface"]["PcieType"] = 22762cd45afSSpencer Ku *generationInUse; 22862cd45afSSpencer Ku } 229dede6a98SJason M. Bills asyncResp->res.jsonValue["PCIeFunctions"] = { 2307e860f15SJohn Edward Broadbent {"@odata.id", 231168e20c1SEd Tanous "/redfish/v1/Systems/system/PCIeDevices/" + 232168e20c1SEd Tanous device + "/PCIeFunctions"}}; 233dede6a98SJason M. Bills }; 234dede6a98SJason M. Bills std::string escapedPath = std::string(pciePath) + "/" + device; 235dede6a98SJason M. Bills dbus::utility::escapePathForDbus(escapedPath); 236dede6a98SJason M. Bills crow::connections::systemBus->async_method_call( 237dede6a98SJason M. Bills std::move(getPCIeDeviceCallback), pcieService, escapedPath, 2387e860f15SJohn Edward Broadbent "org.freedesktop.DBus.Properties", "GetAll", 2397e860f15SJohn Edward Broadbent pcieDeviceInterface); 2407e860f15SJohn Edward Broadbent }); 241dede6a98SJason M. Bills } 242dede6a98SJason M. Bills 2437e860f15SJohn Edward Broadbent inline void requestRoutesSystemPCIeFunctionCollection(App& app) 2447e860f15SJohn Edward Broadbent { 245dede6a98SJason M. Bills /** 246dede6a98SJason M. Bills * Functions triggers appropriate requests on DBus 247dede6a98SJason M. Bills */ 2487e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, 2497e860f15SJohn Edward Broadbent "/redfish/v1/Systems/system/PCIeDevices/<str>/PCIeFunctions/") 250ed398213SEd Tanous .privileges(redfish::privileges::getPCIeFunctionCollection) 2517e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 2527e860f15SJohn Edward Broadbent [](const crow::Request&, 2537e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 2547e860f15SJohn Edward Broadbent const std::string& device) 2557e860f15SJohn Edward Broadbent 256dede6a98SJason M. Bills { 257dede6a98SJason M. Bills asyncResp->res.jsonValue = { 2587e860f15SJohn Edward Broadbent {"@odata.type", 2597e860f15SJohn Edward Broadbent "#PCIeFunctionCollection.PCIeFunctionCollection"}, 2607e860f15SJohn Edward Broadbent {"@odata.id", "/redfish/v1/Systems/system/PCIeDevices/" + 2617e860f15SJohn Edward Broadbent device + "/PCIeFunctions"}, 262dede6a98SJason M. Bills {"Name", "PCIe Function Collection"}, 263dede6a98SJason M. Bills {"Description", 264dede6a98SJason M. Bills "Collection of PCIe Functions for PCIe Device " + device}}; 265dede6a98SJason M. Bills 2667e860f15SJohn Edward Broadbent auto getPCIeDeviceCallback = [asyncResp, device]( 2677e860f15SJohn Edward Broadbent const boost::system::error_code 2687e860f15SJohn Edward Broadbent ec, 2697e860f15SJohn Edward Broadbent boost::container::flat_map< 2707e860f15SJohn Edward Broadbent std::string, 271168e20c1SEd Tanous dbus::utility:: 272168e20c1SEd Tanous DbusVariantType>& 2737e860f15SJohn Edward Broadbent pcieDevProperties) { 2747e860f15SJohn Edward Broadbent if (ec) 2757e860f15SJohn Edward Broadbent { 2767e860f15SJohn Edward Broadbent BMCWEB_LOG_DEBUG 2777e860f15SJohn Edward Broadbent << "failed to get PCIe Device properties ec: " 2787e860f15SJohn Edward Broadbent << ec.value() << ": " << ec.message(); 2797e860f15SJohn Edward Broadbent if (ec.value() == 2807e860f15SJohn Edward Broadbent boost::system::linux_error::bad_request_descriptor) 2817e860f15SJohn Edward Broadbent { 2827e860f15SJohn Edward Broadbent messages::resourceNotFound(asyncResp->res, 2837e860f15SJohn Edward Broadbent "PCIeDevice", device); 2847e860f15SJohn Edward Broadbent } 2857e860f15SJohn Edward Broadbent else 2867e860f15SJohn Edward Broadbent { 2877e860f15SJohn Edward Broadbent messages::internalError(asyncResp->res); 2887e860f15SJohn Edward Broadbent } 2897e860f15SJohn Edward Broadbent return; 2907e860f15SJohn Edward Broadbent } 2917e860f15SJohn Edward Broadbent 2927e860f15SJohn Edward Broadbent nlohmann::json& pcieFunctionList = 2937e860f15SJohn Edward Broadbent asyncResp->res.jsonValue["Members"]; 2947e860f15SJohn Edward Broadbent pcieFunctionList = nlohmann::json::array(); 2957e860f15SJohn Edward Broadbent static constexpr const int maxPciFunctionNum = 8; 2967e860f15SJohn Edward Broadbent for (int functionNum = 0; functionNum < maxPciFunctionNum; 2977e860f15SJohn Edward Broadbent functionNum++) 2987e860f15SJohn Edward Broadbent { 2997e860f15SJohn Edward Broadbent // Check if this function exists by looking for a device 3007e860f15SJohn Edward Broadbent // ID 3017e860f15SJohn Edward Broadbent std::string devIDProperty = 3027e860f15SJohn Edward Broadbent "Function" + std::to_string(functionNum) + 3037e860f15SJohn Edward Broadbent "DeviceId"; 3047e860f15SJohn Edward Broadbent std::string* property = std::get_if<std::string>( 3057e860f15SJohn Edward Broadbent &pcieDevProperties[devIDProperty]); 3067e860f15SJohn Edward Broadbent if (property && !property->empty()) 3077e860f15SJohn Edward Broadbent { 3087e860f15SJohn Edward Broadbent pcieFunctionList.push_back( 3097e860f15SJohn Edward Broadbent {{"@odata.id", 3107e860f15SJohn Edward Broadbent "/redfish/v1/Systems/system/PCIeDevices/" + 3117e860f15SJohn Edward Broadbent device + "/PCIeFunctions/" + 3127e860f15SJohn Edward Broadbent std::to_string(functionNum)}}); 3137e860f15SJohn Edward Broadbent } 3147e860f15SJohn Edward Broadbent } 315*a818d15aSJiaqing Zhao asyncResp->res.jsonValue["Members@odata.count"] = 3167e860f15SJohn Edward Broadbent pcieFunctionList.size(); 3177e860f15SJohn Edward Broadbent }; 3187e860f15SJohn Edward Broadbent std::string escapedPath = std::string(pciePath) + "/" + device; 3197e860f15SJohn Edward Broadbent dbus::utility::escapePathForDbus(escapedPath); 3207e860f15SJohn Edward Broadbent crow::connections::systemBus->async_method_call( 3217e860f15SJohn Edward Broadbent std::move(getPCIeDeviceCallback), pcieService, escapedPath, 3227e860f15SJohn Edward Broadbent "org.freedesktop.DBus.Properties", "GetAll", 3237e860f15SJohn Edward Broadbent pcieDeviceInterface); 3247e860f15SJohn Edward Broadbent }); 3257e860f15SJohn Edward Broadbent } 3267e860f15SJohn Edward Broadbent 3277e860f15SJohn Edward Broadbent inline void requestRoutesSystemPCIeFunction(App& app) 3287e860f15SJohn Edward Broadbent { 3297e860f15SJohn Edward Broadbent BMCWEB_ROUTE( 3307e860f15SJohn Edward Broadbent app, 3317e860f15SJohn Edward Broadbent "/redfish/v1/Systems/system/PCIeDevices/<str>/PCIeFunctions/<str>/") 332ed398213SEd Tanous .privileges(redfish::privileges::getPCIeFunction) 3337e860f15SJohn Edward Broadbent .methods( 3347e860f15SJohn Edward Broadbent boost::beast::http::verb::get)([](const crow::Request&, 3357e860f15SJohn Edward Broadbent const std::shared_ptr< 3367e860f15SJohn Edward Broadbent bmcweb::AsyncResp>& asyncResp, 3377e860f15SJohn Edward Broadbent const std::string& device, 3387e860f15SJohn Edward Broadbent const std::string& function) { 339168e20c1SEd Tanous auto getPCIeDeviceCallback = 340168e20c1SEd Tanous [asyncResp, device, function]( 3417e860f15SJohn Edward Broadbent const boost::system::error_code ec, 342168e20c1SEd Tanous boost::container::flat_map<std::string, 343168e20c1SEd Tanous dbus::utility::DbusVariantType>& 3441214b7e7SGunnar Mills pcieDevProperties) { 345dede6a98SJason M. Bills if (ec) 346dede6a98SJason M. Bills { 347dede6a98SJason M. Bills BMCWEB_LOG_DEBUG 348dede6a98SJason M. Bills << "failed to get PCIe Device properties ec: " 349dede6a98SJason M. Bills << ec.value() << ": " << ec.message(); 350dede6a98SJason M. Bills if (ec.value() == 351dede6a98SJason M. Bills boost::system::linux_error::bad_request_descriptor) 352dede6a98SJason M. Bills { 353168e20c1SEd Tanous messages::resourceNotFound(asyncResp->res, 354168e20c1SEd Tanous "PCIeDevice", device); 355dede6a98SJason M. Bills } 356dede6a98SJason M. Bills else 357dede6a98SJason M. Bills { 358dede6a98SJason M. Bills messages::internalError(asyncResp->res); 359dede6a98SJason M. Bills } 360dede6a98SJason M. Bills return; 361dede6a98SJason M. Bills } 362dede6a98SJason M. Bills 363f5c9f8bdSJason M. Bills // Check if this function exists by looking for a device ID 364168e20c1SEd Tanous std::string devIDProperty = 365168e20c1SEd Tanous "Function" + function + "DeviceId"; 3667e860f15SJohn Edward Broadbent if (std::string* property = std::get_if<std::string>( 3677e860f15SJohn Edward Broadbent &pcieDevProperties[devIDProperty]); 368f5c9f8bdSJason M. Bills property && property->empty()) 369f5c9f8bdSJason M. Bills { 370168e20c1SEd Tanous messages::resourceNotFound(asyncResp->res, 371168e20c1SEd Tanous "PCIeFunction", function); 372f5c9f8bdSJason M. Bills return; 373f5c9f8bdSJason M. Bills } 374f5c9f8bdSJason M. Bills 375f5c9f8bdSJason M. Bills asyncResp->res.jsonValue = { 376f5c9f8bdSJason M. Bills {"@odata.type", "#PCIeFunction.v1_2_0.PCIeFunction"}, 377168e20c1SEd Tanous {"@odata.id", 378168e20c1SEd Tanous "/redfish/v1/Systems/system/PCIeDevices/" + device + 379168e20c1SEd Tanous "/PCIeFunctions/" + function}, 380f5c9f8bdSJason M. Bills {"Name", "PCIe Function"}, 381f5c9f8bdSJason M. Bills {"Id", function}, 382f5c9f8bdSJason M. Bills {"FunctionId", std::stoi(function)}, 383f5c9f8bdSJason M. Bills {"Links", 384f5c9f8bdSJason M. Bills {{"PCIeDevice", 385f5c9f8bdSJason M. Bills {{"@odata.id", 3867e860f15SJohn Edward Broadbent "/redfish/v1/Systems/system/PCIeDevices/" + 3877e860f15SJohn Edward Broadbent device}}}}}}; 388f5c9f8bdSJason M. Bills 3898d78b7a9SPatrick Williams if (std::string* property = std::get_if<std::string>( 390168e20c1SEd Tanous &pcieDevProperties["Function" + function + 391168e20c1SEd Tanous "DeviceId"]); 392f5c9f8bdSJason M. Bills property) 393f5c9f8bdSJason M. Bills { 394f5c9f8bdSJason M. Bills asyncResp->res.jsonValue["DeviceId"] = *property; 395f5c9f8bdSJason M. Bills } 396f5c9f8bdSJason M. Bills 3978d78b7a9SPatrick Williams if (std::string* property = std::get_if<std::string>( 398168e20c1SEd Tanous &pcieDevProperties["Function" + function + 399168e20c1SEd Tanous "VendorId"]); 400f5c9f8bdSJason M. Bills property) 401f5c9f8bdSJason M. Bills { 402f5c9f8bdSJason M. Bills asyncResp->res.jsonValue["VendorId"] = *property; 403f5c9f8bdSJason M. Bills } 404f5c9f8bdSJason M. Bills 4058d78b7a9SPatrick Williams if (std::string* property = std::get_if<std::string>( 4067e860f15SJohn Edward Broadbent &pcieDevProperties["Function" + function + 4077e860f15SJohn Edward Broadbent "FunctionType"]); 408f5c9f8bdSJason M. Bills property) 409f5c9f8bdSJason M. Bills { 410f5c9f8bdSJason M. Bills asyncResp->res.jsonValue["FunctionType"] = *property; 411f5c9f8bdSJason M. Bills } 412f5c9f8bdSJason M. Bills 4138d78b7a9SPatrick Williams if (std::string* property = std::get_if<std::string>( 4147e860f15SJohn Edward Broadbent &pcieDevProperties["Function" + function + 4157e860f15SJohn Edward Broadbent "DeviceClass"]); 416f5c9f8bdSJason M. Bills property) 417f5c9f8bdSJason M. Bills { 418f5c9f8bdSJason M. Bills asyncResp->res.jsonValue["DeviceClass"] = *property; 419f5c9f8bdSJason M. Bills } 420f5c9f8bdSJason M. Bills 4218d78b7a9SPatrick Williams if (std::string* property = std::get_if<std::string>( 4227e860f15SJohn Edward Broadbent &pcieDevProperties["Function" + function + 4237e860f15SJohn Edward Broadbent "ClassCode"]); 424f5c9f8bdSJason M. Bills property) 425f5c9f8bdSJason M. Bills { 426f5c9f8bdSJason M. Bills asyncResp->res.jsonValue["ClassCode"] = *property; 427f5c9f8bdSJason M. Bills } 428f5c9f8bdSJason M. Bills 4298d78b7a9SPatrick Williams if (std::string* property = std::get_if<std::string>( 4307e860f15SJohn Edward Broadbent &pcieDevProperties["Function" + function + 4317e860f15SJohn Edward Broadbent "RevisionId"]); 432f5c9f8bdSJason M. Bills property) 433f5c9f8bdSJason M. Bills { 434f5c9f8bdSJason M. Bills asyncResp->res.jsonValue["RevisionId"] = *property; 435f5c9f8bdSJason M. Bills } 436f5c9f8bdSJason M. Bills 4378d78b7a9SPatrick Williams if (std::string* property = std::get_if<std::string>( 4387e860f15SJohn Edward Broadbent &pcieDevProperties["Function" + function + 4397e860f15SJohn Edward Broadbent "SubsystemId"]); 440f5c9f8bdSJason M. Bills property) 441f5c9f8bdSJason M. Bills { 442f5c9f8bdSJason M. Bills asyncResp->res.jsonValue["SubsystemId"] = *property; 443f5c9f8bdSJason M. Bills } 444f5c9f8bdSJason M. Bills 4458d78b7a9SPatrick Williams if (std::string* property = std::get_if<std::string>( 446f5c9f8bdSJason M. Bills &pcieDevProperties["Function" + function + 447f5c9f8bdSJason M. Bills "SubsystemVendorId"]); 448f5c9f8bdSJason M. Bills property) 449f5c9f8bdSJason M. Bills { 450168e20c1SEd Tanous asyncResp->res.jsonValue["SubsystemVendorId"] = 451168e20c1SEd Tanous *property; 452f5c9f8bdSJason M. Bills } 453f5c9f8bdSJason M. Bills }; 454f5c9f8bdSJason M. Bills std::string escapedPath = std::string(pciePath) + "/" + device; 455f5c9f8bdSJason M. Bills dbus::utility::escapePathForDbus(escapedPath); 456f5c9f8bdSJason M. Bills crow::connections::systemBus->async_method_call( 457f5c9f8bdSJason M. Bills std::move(getPCIeDeviceCallback), pcieService, escapedPath, 4587e860f15SJohn Edward Broadbent "org.freedesktop.DBus.Properties", "GetAll", 4597e860f15SJohn Edward Broadbent pcieDeviceInterface); 4607e860f15SJohn Edward Broadbent }); 461f5c9f8bdSJason M. Bills } 462f5c9f8bdSJason M. Bills 463f5c9f8bdSJason M. Bills } // namespace redfish 464