1f5c9f8bdSJason M. Bills /* 2f5c9f8bdSJason M. Bills // Copyright (c) 2018 Intel Corporation 3f5c9f8bdSJason M. Bills // 4f5c9f8bdSJason M. Bills // Licensed under the Apache License, Version 2.0 (the "License"); 5f5c9f8bdSJason M. Bills // you may not use this file except in compliance with the License. 6f5c9f8bdSJason M. Bills // You may obtain a copy of the License at 7f5c9f8bdSJason M. Bills // 8f5c9f8bdSJason M. Bills // http://www.apache.org/licenses/LICENSE-2.0 9f5c9f8bdSJason M. Bills // 10f5c9f8bdSJason M. Bills // Unless required by applicable law or agreed to in writing, software 11f5c9f8bdSJason M. Bills // distributed under the License is distributed on an "AS IS" BASIS, 12f5c9f8bdSJason M. Bills // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f5c9f8bdSJason M. Bills // See the License for the specific language governing permissions and 14f5c9f8bdSJason M. Bills // limitations under the License. 15f5c9f8bdSJason M. Bills */ 16f5c9f8bdSJason M. Bills 17f5c9f8bdSJason M. Bills #pragma once 18f5c9f8bdSJason M. Bills 19f5c9f8bdSJason M. Bills #include "node.hpp" 20f5c9f8bdSJason M. Bills 21f5c9f8bdSJason M. Bills #include <boost/system/linux_error.hpp> 22f5c9f8bdSJason M. Bills 23f5c9f8bdSJason M. Bills namespace redfish 24f5c9f8bdSJason M. Bills { 25f5c9f8bdSJason M. Bills 26f5c9f8bdSJason M. Bills static constexpr char const* pcieService = "xyz.openbmc_project.PCIe"; 27f5c9f8bdSJason M. Bills static constexpr char const* pciePath = "/xyz/openbmc_project/PCIe"; 28f5c9f8bdSJason M. Bills static constexpr char const* pcieDeviceInterface = 29f5c9f8bdSJason M. Bills "xyz.openbmc_project.PCIe.Device"; 30f5c9f8bdSJason M. Bills 31*b5a76932SEd Tanous static inline void 32*b5a76932SEd Tanous getPCIeDeviceList(const std::shared_ptr<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 73adbe192aSJason M. Bills class SystemPCIeDeviceCollection : public Node 74adbe192aSJason M. Bills { 75adbe192aSJason M. Bills public: 7652cc112dSEd Tanous SystemPCIeDeviceCollection(App& app) : 77adbe192aSJason M. Bills Node(app, "/redfish/v1/Systems/system/PCIeDevices/") 78adbe192aSJason M. Bills { 79adbe192aSJason M. Bills entityPrivileges = { 80adbe192aSJason M. Bills {boost::beast::http::verb::get, {{"Login"}}}, 81adbe192aSJason M. Bills {boost::beast::http::verb::head, {{"Login"}}}, 82adbe192aSJason M. Bills {boost::beast::http::verb::patch, {{"ConfigureManager"}}}, 83adbe192aSJason M. Bills {boost::beast::http::verb::put, {{"ConfigureManager"}}}, 84adbe192aSJason M. Bills {boost::beast::http::verb::delete_, {{"ConfigureManager"}}}, 85adbe192aSJason M. Bills {boost::beast::http::verb::post, {{"ConfigureManager"}}}}; 86adbe192aSJason M. Bills } 87adbe192aSJason M. Bills 88adbe192aSJason M. Bills private: 89adbe192aSJason M. Bills /** 90adbe192aSJason M. Bills * Functions triggers appropriate requests on DBus 91adbe192aSJason M. Bills */ 92cb13a392SEd Tanous void doGet(crow::Response& res, const crow::Request&, 93cb13a392SEd Tanous const std::vector<std::string>&) override 94adbe192aSJason M. Bills { 95adbe192aSJason M. Bills std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); 96adbe192aSJason M. Bills asyncResp->res.jsonValue = { 97adbe192aSJason M. Bills {"@odata.type", "#PCIeDeviceCollection.PCIeDeviceCollection"}, 98adbe192aSJason M. Bills {"@odata.id", "/redfish/v1/Systems/system/PCIeDevices"}, 99adbe192aSJason M. Bills {"Name", "PCIe Device Collection"}, 100adbe192aSJason M. Bills {"Description", "Collection of PCIe Devices"}, 101adbe192aSJason M. Bills {"Members", nlohmann::json::array()}, 102adbe192aSJason M. Bills {"Members@odata.count", 0}}; 103adbe192aSJason M. Bills getPCIeDeviceList(asyncResp, "Members"); 104adbe192aSJason M. Bills } 105adbe192aSJason M. Bills }; 106adbe192aSJason M. Bills 107f5c9f8bdSJason M. Bills class SystemPCIeDevice : public Node 108f5c9f8bdSJason M. Bills { 109f5c9f8bdSJason M. Bills public: 11052cc112dSEd Tanous SystemPCIeDevice(App& app) : 111f5c9f8bdSJason M. Bills Node(app, "/redfish/v1/Systems/system/PCIeDevices/<str>/", 112f5c9f8bdSJason M. Bills std::string()) 113f5c9f8bdSJason M. Bills { 114f5c9f8bdSJason M. Bills entityPrivileges = { 115f5c9f8bdSJason M. Bills {boost::beast::http::verb::get, {{"Login"}}}, 116f5c9f8bdSJason M. Bills {boost::beast::http::verb::head, {{"Login"}}}, 117f5c9f8bdSJason M. Bills {boost::beast::http::verb::patch, {{"ConfigureManager"}}}, 118f5c9f8bdSJason M. Bills {boost::beast::http::verb::put, {{"ConfigureManager"}}}, 119f5c9f8bdSJason M. Bills {boost::beast::http::verb::delete_, {{"ConfigureManager"}}}, 120f5c9f8bdSJason M. Bills {boost::beast::http::verb::post, {{"ConfigureManager"}}}}; 121f5c9f8bdSJason M. Bills } 122f5c9f8bdSJason M. Bills 123f5c9f8bdSJason M. Bills private: 124cb13a392SEd Tanous void doGet(crow::Response& res, const crow::Request&, 125f5c9f8bdSJason M. Bills const std::vector<std::string>& params) override 126f5c9f8bdSJason M. Bills { 127f5c9f8bdSJason M. Bills std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); 128f5c9f8bdSJason M. Bills if (params.size() != 1) 129f5c9f8bdSJason M. Bills { 130f5c9f8bdSJason M. Bills messages::internalError(asyncResp->res); 131f5c9f8bdSJason M. Bills return; 132f5c9f8bdSJason M. Bills } 133f5c9f8bdSJason M. Bills const std::string& device = params[0]; 134f5c9f8bdSJason M. Bills 135f5c9f8bdSJason M. Bills auto getPCIeDeviceCallback = 136f5c9f8bdSJason M. Bills [asyncResp, 137f5c9f8bdSJason M. Bills device](const boost::system::error_code ec, 13819bd78d9SPatrick Williams boost::container::flat_map<std::string, 1391214b7e7SGunnar Mills std::variant<std::string>>& 1401214b7e7SGunnar Mills pcieDevProperties) { 141f5c9f8bdSJason M. Bills if (ec) 142f5c9f8bdSJason M. Bills { 143f5c9f8bdSJason M. Bills BMCWEB_LOG_DEBUG 144f5c9f8bdSJason M. Bills << "failed to get PCIe Device properties ec: " 145271584abSEd Tanous << ec.value() << ": " << ec.message(); 146f5c9f8bdSJason M. Bills if (ec.value() == 147f5c9f8bdSJason M. Bills boost::system::linux_error::bad_request_descriptor) 148f5c9f8bdSJason M. Bills { 149f5c9f8bdSJason M. Bills messages::resourceNotFound(asyncResp->res, "PCIeDevice", 150f5c9f8bdSJason M. Bills device); 151f5c9f8bdSJason M. Bills } 152f5c9f8bdSJason M. Bills else 153f5c9f8bdSJason M. Bills { 154f5c9f8bdSJason M. Bills messages::internalError(asyncResp->res); 155f5c9f8bdSJason M. Bills } 156f5c9f8bdSJason M. Bills return; 157f5c9f8bdSJason M. Bills } 158f5c9f8bdSJason M. Bills 159f5c9f8bdSJason M. Bills asyncResp->res.jsonValue = { 160dede6a98SJason M. Bills {"@odata.type", "#PCIeDevice.v1_4_0.PCIeDevice"}, 161f5c9f8bdSJason M. Bills {"@odata.id", 162f5c9f8bdSJason M. Bills "/redfish/v1/Systems/system/PCIeDevices/" + device}, 163f5c9f8bdSJason M. Bills {"Name", "PCIe Device"}, 164f5c9f8bdSJason M. Bills {"Id", device}}; 165f5c9f8bdSJason M. Bills 1668d78b7a9SPatrick Williams if (std::string* property = std::get_if<std::string>( 167f5c9f8bdSJason M. Bills &pcieDevProperties["Manufacturer"]); 168f5c9f8bdSJason M. Bills property) 169f5c9f8bdSJason M. Bills { 170f5c9f8bdSJason M. Bills asyncResp->res.jsonValue["Manufacturer"] = *property; 171f5c9f8bdSJason M. Bills } 172f5c9f8bdSJason M. Bills 1738d78b7a9SPatrick Williams if (std::string* property = std::get_if<std::string>( 174f5c9f8bdSJason M. Bills &pcieDevProperties["DeviceType"]); 175f5c9f8bdSJason M. Bills property) 176f5c9f8bdSJason M. Bills { 177f5c9f8bdSJason M. Bills asyncResp->res.jsonValue["DeviceType"] = *property; 178f5c9f8bdSJason M. Bills } 179f5c9f8bdSJason M. Bills 180dede6a98SJason M. Bills asyncResp->res.jsonValue["PCIeFunctions"] = { 181dede6a98SJason M. Bills {"@odata.id", "/redfish/v1/Systems/system/PCIeDevices/" + 182dede6a98SJason M. Bills device + "/PCIeFunctions"}}; 183dede6a98SJason M. Bills }; 184dede6a98SJason M. Bills std::string escapedPath = std::string(pciePath) + "/" + device; 185dede6a98SJason M. Bills dbus::utility::escapePathForDbus(escapedPath); 186dede6a98SJason M. Bills crow::connections::systemBus->async_method_call( 187dede6a98SJason M. Bills std::move(getPCIeDeviceCallback), pcieService, escapedPath, 188dede6a98SJason M. Bills "org.freedesktop.DBus.Properties", "GetAll", pcieDeviceInterface); 189dede6a98SJason M. Bills } 190dede6a98SJason M. Bills }; 191dede6a98SJason M. Bills 192dede6a98SJason M. Bills class SystemPCIeFunctionCollection : public Node 193dede6a98SJason M. Bills { 194dede6a98SJason M. Bills public: 19552cc112dSEd Tanous SystemPCIeFunctionCollection(App& app) : 196dede6a98SJason M. Bills Node(app, "/redfish/v1/Systems/system/PCIeDevices/<str>/PCIeFunctions/", 197dede6a98SJason M. Bills std::string()) 198dede6a98SJason M. Bills { 199dede6a98SJason M. Bills entityPrivileges = { 200dede6a98SJason M. Bills {boost::beast::http::verb::get, {{"Login"}}}, 201dede6a98SJason M. Bills {boost::beast::http::verb::head, {{"Login"}}}, 202dede6a98SJason M. Bills {boost::beast::http::verb::patch, {{"ConfigureManager"}}}, 203dede6a98SJason M. Bills {boost::beast::http::verb::put, {{"ConfigureManager"}}}, 204dede6a98SJason M. Bills {boost::beast::http::verb::delete_, {{"ConfigureManager"}}}, 205dede6a98SJason M. Bills {boost::beast::http::verb::post, {{"ConfigureManager"}}}}; 206dede6a98SJason M. Bills } 207dede6a98SJason M. Bills 208dede6a98SJason M. Bills private: 209dede6a98SJason M. Bills /** 210dede6a98SJason M. Bills * Functions triggers appropriate requests on DBus 211dede6a98SJason M. Bills */ 212cb13a392SEd Tanous void doGet(crow::Response& res, const crow::Request&, 213dede6a98SJason M. Bills const std::vector<std::string>& params) override 214dede6a98SJason M. Bills { 215dede6a98SJason M. Bills std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); 216dede6a98SJason M. Bills if (params.size() != 1) 217dede6a98SJason M. Bills { 218dede6a98SJason M. Bills messages::internalError(asyncResp->res); 219dede6a98SJason M. Bills return; 220dede6a98SJason M. Bills } 221dede6a98SJason M. Bills const std::string& device = params[0]; 222dede6a98SJason M. Bills asyncResp->res.jsonValue = { 223dede6a98SJason M. Bills {"@odata.type", "#PCIeFunctionCollection.PCIeFunctionCollection"}, 224dede6a98SJason M. Bills {"@odata.id", "/redfish/v1/Systems/system/PCIeDevices/" + device + 225dede6a98SJason M. Bills "/PCIeFunctions"}, 226dede6a98SJason M. Bills {"Name", "PCIe Function Collection"}, 227dede6a98SJason M. Bills {"Description", 228dede6a98SJason M. Bills "Collection of PCIe Functions for PCIe Device " + device}}; 229dede6a98SJason M. Bills 230dede6a98SJason M. Bills auto getPCIeDeviceCallback = 231dede6a98SJason M. Bills [asyncResp, 232dede6a98SJason M. Bills device](const boost::system::error_code ec, 23319bd78d9SPatrick Williams boost::container::flat_map<std::string, 2341214b7e7SGunnar Mills std::variant<std::string>>& 2351214b7e7SGunnar Mills pcieDevProperties) { 236dede6a98SJason M. Bills if (ec) 237dede6a98SJason M. Bills { 238dede6a98SJason M. Bills BMCWEB_LOG_DEBUG 239dede6a98SJason M. Bills << "failed to get PCIe Device properties ec: " 240dede6a98SJason M. Bills << ec.value() << ": " << ec.message(); 241dede6a98SJason M. Bills if (ec.value() == 242dede6a98SJason M. Bills boost::system::linux_error::bad_request_descriptor) 243dede6a98SJason M. Bills { 244dede6a98SJason M. Bills messages::resourceNotFound(asyncResp->res, "PCIeDevice", 245dede6a98SJason M. Bills device); 246dede6a98SJason M. Bills } 247dede6a98SJason M. Bills else 248dede6a98SJason M. Bills { 249dede6a98SJason M. Bills messages::internalError(asyncResp->res); 250dede6a98SJason M. Bills } 251dede6a98SJason M. Bills return; 252dede6a98SJason M. Bills } 253dede6a98SJason M. Bills 254f5c9f8bdSJason M. Bills nlohmann::json& pcieFunctionList = 255dede6a98SJason M. Bills asyncResp->res.jsonValue["Members"]; 256f5c9f8bdSJason M. Bills pcieFunctionList = nlohmann::json::array(); 257f5c9f8bdSJason M. Bills static constexpr const int maxPciFunctionNum = 8; 258f5c9f8bdSJason M. Bills for (int functionNum = 0; functionNum < maxPciFunctionNum; 259f5c9f8bdSJason M. Bills functionNum++) 260f5c9f8bdSJason M. Bills { 261f5c9f8bdSJason M. Bills // Check if this function exists by looking for a device ID 262f5c9f8bdSJason M. Bills std::string devIDProperty = 263f5c9f8bdSJason M. Bills "Function" + std::to_string(functionNum) + "DeviceId"; 2648d78b7a9SPatrick Williams std::string* property = std::get_if<std::string>( 265f5c9f8bdSJason M. Bills &pcieDevProperties[devIDProperty]); 266dede6a98SJason M. Bills if (property && !property->empty()) 267f5c9f8bdSJason M. Bills { 268f5c9f8bdSJason M. Bills pcieFunctionList.push_back( 269f5c9f8bdSJason M. Bills {{"@odata.id", 270f5c9f8bdSJason M. Bills "/redfish/v1/Systems/system/PCIeDevices/" + 271f5c9f8bdSJason M. Bills device + "/PCIeFunctions/" + 272f5c9f8bdSJason M. Bills std::to_string(functionNum)}}); 273f5c9f8bdSJason M. Bills } 274f5c9f8bdSJason M. Bills } 275dede6a98SJason M. Bills asyncResp->res.jsonValue["PCIeFunctions@odata.count"] = 276f5c9f8bdSJason M. Bills pcieFunctionList.size(); 277f5c9f8bdSJason M. Bills }; 278f5c9f8bdSJason M. Bills std::string escapedPath = std::string(pciePath) + "/" + device; 279f5c9f8bdSJason M. Bills dbus::utility::escapePathForDbus(escapedPath); 280f5c9f8bdSJason M. Bills crow::connections::systemBus->async_method_call( 281f5c9f8bdSJason M. Bills std::move(getPCIeDeviceCallback), pcieService, escapedPath, 282f5c9f8bdSJason M. Bills "org.freedesktop.DBus.Properties", "GetAll", pcieDeviceInterface); 283f5c9f8bdSJason M. Bills } 284f5c9f8bdSJason M. Bills }; 285f5c9f8bdSJason M. Bills 286f5c9f8bdSJason M. Bills class SystemPCIeFunction : public Node 287f5c9f8bdSJason M. Bills { 288f5c9f8bdSJason M. Bills public: 28952cc112dSEd Tanous SystemPCIeFunction(App& app) : 290f5c9f8bdSJason M. Bills Node( 291f5c9f8bdSJason M. Bills app, 292f5c9f8bdSJason M. Bills "/redfish/v1/Systems/system/PCIeDevices/<str>/PCIeFunctions/<str>/", 293f5c9f8bdSJason M. Bills std::string(), std::string()) 294f5c9f8bdSJason M. Bills { 295f5c9f8bdSJason M. Bills entityPrivileges = { 296f5c9f8bdSJason M. Bills {boost::beast::http::verb::get, {{"Login"}}}, 297f5c9f8bdSJason M. Bills {boost::beast::http::verb::head, {{"Login"}}}, 298f5c9f8bdSJason M. Bills {boost::beast::http::verb::patch, {{"ConfigureManager"}}}, 299f5c9f8bdSJason M. Bills {boost::beast::http::verb::put, {{"ConfigureManager"}}}, 300f5c9f8bdSJason M. Bills {boost::beast::http::verb::delete_, {{"ConfigureManager"}}}, 301f5c9f8bdSJason M. Bills {boost::beast::http::verb::post, {{"ConfigureManager"}}}}; 302f5c9f8bdSJason M. Bills } 303f5c9f8bdSJason M. Bills 304f5c9f8bdSJason M. Bills private: 305cb13a392SEd Tanous void doGet(crow::Response& res, const crow::Request&, 306f5c9f8bdSJason M. Bills const std::vector<std::string>& params) override 307f5c9f8bdSJason M. Bills { 308f5c9f8bdSJason M. Bills std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); 309f5c9f8bdSJason M. Bills if (params.size() != 2) 310f5c9f8bdSJason M. Bills { 311f5c9f8bdSJason M. Bills messages::internalError(asyncResp->res); 312f5c9f8bdSJason M. Bills return; 313f5c9f8bdSJason M. Bills } 314f5c9f8bdSJason M. Bills const std::string& device = params[0]; 315f5c9f8bdSJason M. Bills const std::string& function = params[1]; 316f5c9f8bdSJason M. Bills 3178d78b7a9SPatrick Williams auto getPCIeDeviceCallback = [asyncResp, device, function]( 318f5c9f8bdSJason M. Bills const boost::system::error_code ec, 319f5c9f8bdSJason M. Bills boost::container::flat_map< 3208d78b7a9SPatrick Williams std::string, 3211214b7e7SGunnar Mills std::variant<std::string>>& 3221214b7e7SGunnar Mills pcieDevProperties) { 323f5c9f8bdSJason M. Bills if (ec) 324f5c9f8bdSJason M. Bills { 325f5c9f8bdSJason M. Bills BMCWEB_LOG_DEBUG 3268d78b7a9SPatrick Williams << "failed to get PCIe Device properties ec: " << ec.value() 3278d78b7a9SPatrick Williams << ": " << ec.message(); 328f5c9f8bdSJason M. Bills if (ec.value() == 329f5c9f8bdSJason M. Bills boost::system::linux_error::bad_request_descriptor) 330f5c9f8bdSJason M. Bills { 331f5c9f8bdSJason M. Bills messages::resourceNotFound(asyncResp->res, "PCIeDevice", 332f5c9f8bdSJason M. Bills device); 333f5c9f8bdSJason M. Bills } 334f5c9f8bdSJason M. Bills else 335f5c9f8bdSJason M. Bills { 336f5c9f8bdSJason M. Bills messages::internalError(asyncResp->res); 337f5c9f8bdSJason M. Bills } 338f5c9f8bdSJason M. Bills return; 339f5c9f8bdSJason M. Bills } 340f5c9f8bdSJason M. Bills 341f5c9f8bdSJason M. Bills // Check if this function exists by looking for a device ID 342f5c9f8bdSJason M. Bills std::string devIDProperty = "Function" + function + "DeviceId"; 343f5c9f8bdSJason M. Bills if (std::string* property = 3448d78b7a9SPatrick Williams std::get_if<std::string>(&pcieDevProperties[devIDProperty]); 345f5c9f8bdSJason M. Bills property && property->empty()) 346f5c9f8bdSJason M. Bills { 347f5c9f8bdSJason M. Bills messages::resourceNotFound(asyncResp->res, "PCIeFunction", 348f5c9f8bdSJason M. Bills function); 349f5c9f8bdSJason M. Bills return; 350f5c9f8bdSJason M. Bills } 351f5c9f8bdSJason M. Bills 352f5c9f8bdSJason M. Bills asyncResp->res.jsonValue = { 353f5c9f8bdSJason M. Bills {"@odata.type", "#PCIeFunction.v1_2_0.PCIeFunction"}, 354f5c9f8bdSJason M. Bills {"@odata.id", "/redfish/v1/Systems/system/PCIeDevices/" + 355f5c9f8bdSJason M. Bills device + "/PCIeFunctions/" + function}, 356f5c9f8bdSJason M. Bills {"Name", "PCIe Function"}, 357f5c9f8bdSJason M. Bills {"Id", function}, 358f5c9f8bdSJason M. Bills {"FunctionId", std::stoi(function)}, 359f5c9f8bdSJason M. Bills {"Links", 360f5c9f8bdSJason M. Bills {{"PCIeDevice", 361f5c9f8bdSJason M. Bills {{"@odata.id", 3628d78b7a9SPatrick Williams "/redfish/v1/Systems/system/PCIeDevices/" + device}}}}}}; 363f5c9f8bdSJason M. Bills 3648d78b7a9SPatrick Williams if (std::string* property = std::get_if<std::string>( 3658d78b7a9SPatrick Williams &pcieDevProperties["Function" + function + "DeviceId"]); 366f5c9f8bdSJason M. Bills property) 367f5c9f8bdSJason M. Bills { 368f5c9f8bdSJason M. Bills asyncResp->res.jsonValue["DeviceId"] = *property; 369f5c9f8bdSJason M. Bills } 370f5c9f8bdSJason M. Bills 3718d78b7a9SPatrick Williams if (std::string* property = std::get_if<std::string>( 3728d78b7a9SPatrick Williams &pcieDevProperties["Function" + function + "VendorId"]); 373f5c9f8bdSJason M. Bills property) 374f5c9f8bdSJason M. Bills { 375f5c9f8bdSJason M. Bills asyncResp->res.jsonValue["VendorId"] = *property; 376f5c9f8bdSJason M. Bills } 377f5c9f8bdSJason M. Bills 3788d78b7a9SPatrick Williams if (std::string* property = std::get_if<std::string>( 3798d78b7a9SPatrick Williams &pcieDevProperties["Function" + function + "FunctionType"]); 380f5c9f8bdSJason M. Bills property) 381f5c9f8bdSJason M. Bills { 382f5c9f8bdSJason M. Bills asyncResp->res.jsonValue["FunctionType"] = *property; 383f5c9f8bdSJason M. Bills } 384f5c9f8bdSJason M. Bills 3858d78b7a9SPatrick Williams if (std::string* property = std::get_if<std::string>( 3868d78b7a9SPatrick Williams &pcieDevProperties["Function" + function + "DeviceClass"]); 387f5c9f8bdSJason M. Bills property) 388f5c9f8bdSJason M. Bills { 389f5c9f8bdSJason M. Bills asyncResp->res.jsonValue["DeviceClass"] = *property; 390f5c9f8bdSJason M. Bills } 391f5c9f8bdSJason M. Bills 3928d78b7a9SPatrick Williams if (std::string* property = std::get_if<std::string>( 3938d78b7a9SPatrick Williams &pcieDevProperties["Function" + function + "ClassCode"]); 394f5c9f8bdSJason M. Bills property) 395f5c9f8bdSJason M. Bills { 396f5c9f8bdSJason M. Bills asyncResp->res.jsonValue["ClassCode"] = *property; 397f5c9f8bdSJason M. Bills } 398f5c9f8bdSJason M. Bills 3998d78b7a9SPatrick Williams if (std::string* property = std::get_if<std::string>( 4008d78b7a9SPatrick Williams &pcieDevProperties["Function" + function + "RevisionId"]); 401f5c9f8bdSJason M. Bills property) 402f5c9f8bdSJason M. Bills { 403f5c9f8bdSJason M. Bills asyncResp->res.jsonValue["RevisionId"] = *property; 404f5c9f8bdSJason M. Bills } 405f5c9f8bdSJason M. Bills 4068d78b7a9SPatrick Williams if (std::string* property = std::get_if<std::string>( 4078d78b7a9SPatrick Williams &pcieDevProperties["Function" + function + "SubsystemId"]); 408f5c9f8bdSJason M. Bills property) 409f5c9f8bdSJason M. Bills { 410f5c9f8bdSJason M. Bills asyncResp->res.jsonValue["SubsystemId"] = *property; 411f5c9f8bdSJason M. Bills } 412f5c9f8bdSJason M. Bills 4138d78b7a9SPatrick Williams if (std::string* property = std::get_if<std::string>( 414f5c9f8bdSJason M. Bills &pcieDevProperties["Function" + function + 415f5c9f8bdSJason M. Bills "SubsystemVendorId"]); 416f5c9f8bdSJason M. Bills property) 417f5c9f8bdSJason M. Bills { 418f5c9f8bdSJason M. Bills asyncResp->res.jsonValue["SubsystemVendorId"] = *property; 419f5c9f8bdSJason M. Bills } 420f5c9f8bdSJason M. Bills }; 421f5c9f8bdSJason M. Bills std::string escapedPath = std::string(pciePath) + "/" + device; 422f5c9f8bdSJason M. Bills dbus::utility::escapePathForDbus(escapedPath); 423f5c9f8bdSJason M. Bills crow::connections::systemBus->async_method_call( 424f5c9f8bdSJason M. Bills std::move(getPCIeDeviceCallback), pcieService, escapedPath, 425f5c9f8bdSJason M. Bills "org.freedesktop.DBus.Properties", "GetAll", pcieDeviceInterface); 426f5c9f8bdSJason M. Bills } 427f5c9f8bdSJason M. Bills }; 428f5c9f8bdSJason M. Bills 429f5c9f8bdSJason M. Bills } // namespace redfish 430