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*adbe192aSJason M. Bills static inline void getPCIeDeviceList(std::shared_ptr<AsyncResp> asyncResp, 32*adbe192aSJason M. Bills const std::string &name) 33f5c9f8bdSJason M. Bills { 34*adbe192aSJason M. Bills auto getPCIeMapCallback = [asyncResp, name]( 35*adbe192aSJason M. Bills const boost::system::error_code ec, 36f5c9f8bdSJason M. Bills std::vector<std::string> &pcieDevicePaths) { 37f5c9f8bdSJason M. Bills if (ec) 38f5c9f8bdSJason M. Bills { 39a2730f01SAndrew Geissler BMCWEB_LOG_DEBUG << "no PCIe device paths found ec: " 40f5c9f8bdSJason M. Bills << ec.message(); 41a2730f01SAndrew Geissler // Not an error, system just doesn't have PCIe info 42f5c9f8bdSJason M. Bills return; 43f5c9f8bdSJason M. Bills } 44*adbe192aSJason M. Bills nlohmann::json &pcieDeviceList = asyncResp->res.jsonValue[name]; 45f5c9f8bdSJason M. Bills pcieDeviceList = nlohmann::json::array(); 46f5c9f8bdSJason M. Bills for (const std::string &pcieDevicePath : pcieDevicePaths) 47f5c9f8bdSJason M. Bills { 48f5c9f8bdSJason M. Bills size_t devStart = pcieDevicePath.rfind("/"); 49f5c9f8bdSJason M. Bills if (devStart == std::string::npos) 50f5c9f8bdSJason M. Bills { 51f5c9f8bdSJason M. Bills continue; 52f5c9f8bdSJason M. Bills } 53f5c9f8bdSJason M. Bills 54f5c9f8bdSJason M. Bills std::string devName = pcieDevicePath.substr(devStart + 1); 55f5c9f8bdSJason M. Bills if (devName.empty()) 56f5c9f8bdSJason M. Bills { 57f5c9f8bdSJason M. Bills continue; 58f5c9f8bdSJason M. Bills } 59f5c9f8bdSJason M. Bills pcieDeviceList.push_back( 60f5c9f8bdSJason M. Bills {{"@odata.id", 61f5c9f8bdSJason M. Bills "/redfish/v1/Systems/system/PCIeDevices/" + devName}}); 62f5c9f8bdSJason M. Bills } 63*adbe192aSJason M. Bills asyncResp->res.jsonValue[name + "@odata.count"] = pcieDeviceList.size(); 64f5c9f8bdSJason M. Bills }; 65f5c9f8bdSJason M. Bills crow::connections::systemBus->async_method_call( 66f5c9f8bdSJason M. Bills std::move(getPCIeMapCallback), "xyz.openbmc_project.ObjectMapper", 67f5c9f8bdSJason M. Bills "/xyz/openbmc_project/object_mapper", 68f5c9f8bdSJason M. Bills "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", 69f5c9f8bdSJason M. Bills std::string(pciePath) + "/", 1, std::array<std::string, 0>()); 70f5c9f8bdSJason M. Bills } 71f5c9f8bdSJason M. Bills 72*adbe192aSJason M. Bills class SystemPCIeDeviceCollection : public Node 73*adbe192aSJason M. Bills { 74*adbe192aSJason M. Bills public: 75*adbe192aSJason M. Bills template <typename CrowApp> 76*adbe192aSJason M. Bills SystemPCIeDeviceCollection(CrowApp &app) : 77*adbe192aSJason M. Bills Node(app, "/redfish/v1/Systems/system/PCIeDevices/") 78*adbe192aSJason M. Bills { 79*adbe192aSJason M. Bills entityPrivileges = { 80*adbe192aSJason M. Bills {boost::beast::http::verb::get, {{"Login"}}}, 81*adbe192aSJason M. Bills {boost::beast::http::verb::head, {{"Login"}}}, 82*adbe192aSJason M. Bills {boost::beast::http::verb::patch, {{"ConfigureManager"}}}, 83*adbe192aSJason M. Bills {boost::beast::http::verb::put, {{"ConfigureManager"}}}, 84*adbe192aSJason M. Bills {boost::beast::http::verb::delete_, {{"ConfigureManager"}}}, 85*adbe192aSJason M. Bills {boost::beast::http::verb::post, {{"ConfigureManager"}}}}; 86*adbe192aSJason M. Bills } 87*adbe192aSJason M. Bills 88*adbe192aSJason M. Bills private: 89*adbe192aSJason M. Bills /** 90*adbe192aSJason M. Bills * Functions triggers appropriate requests on DBus 91*adbe192aSJason M. Bills */ 92*adbe192aSJason M. Bills void doGet(crow::Response &res, const crow::Request &req, 93*adbe192aSJason M. Bills const std::vector<std::string> ¶ms) override 94*adbe192aSJason M. Bills { 95*adbe192aSJason M. Bills std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); 96*adbe192aSJason M. Bills asyncResp->res.jsonValue = { 97*adbe192aSJason M. Bills {"@odata.type", "#PCIeDeviceCollection.PCIeDeviceCollection"}, 98*adbe192aSJason M. Bills {"@odata.context", 99*adbe192aSJason M. Bills "/redfish/v1/" 100*adbe192aSJason M. Bills "$metadata#PCIeDeviceCollection.PCIeDeviceCollection"}, 101*adbe192aSJason M. Bills {"@odata.id", "/redfish/v1/Systems/system/PCIeDevices"}, 102*adbe192aSJason M. Bills {"Name", "PCIe Device Collection"}, 103*adbe192aSJason M. Bills {"Description", "Collection of PCIe Devices"}, 104*adbe192aSJason M. Bills {"Members", nlohmann::json::array()}, 105*adbe192aSJason M. Bills {"Members@odata.count", 0}}; 106*adbe192aSJason M. Bills getPCIeDeviceList(asyncResp, "Members"); 107*adbe192aSJason M. Bills } 108*adbe192aSJason M. Bills }; 109*adbe192aSJason M. Bills 110f5c9f8bdSJason M. Bills class SystemPCIeDevice : public Node 111f5c9f8bdSJason M. Bills { 112f5c9f8bdSJason M. Bills public: 113f5c9f8bdSJason M. Bills SystemPCIeDevice(CrowApp &app) : 114f5c9f8bdSJason M. Bills Node(app, "/redfish/v1/Systems/system/PCIeDevices/<str>/", 115f5c9f8bdSJason M. Bills std::string()) 116f5c9f8bdSJason M. Bills { 117f5c9f8bdSJason M. Bills entityPrivileges = { 118f5c9f8bdSJason M. Bills {boost::beast::http::verb::get, {{"Login"}}}, 119f5c9f8bdSJason M. Bills {boost::beast::http::verb::head, {{"Login"}}}, 120f5c9f8bdSJason M. Bills {boost::beast::http::verb::patch, {{"ConfigureManager"}}}, 121f5c9f8bdSJason M. Bills {boost::beast::http::verb::put, {{"ConfigureManager"}}}, 122f5c9f8bdSJason M. Bills {boost::beast::http::verb::delete_, {{"ConfigureManager"}}}, 123f5c9f8bdSJason M. Bills {boost::beast::http::verb::post, {{"ConfigureManager"}}}}; 124f5c9f8bdSJason M. Bills } 125f5c9f8bdSJason M. Bills 126f5c9f8bdSJason M. Bills private: 127f5c9f8bdSJason M. Bills void doGet(crow::Response &res, const crow::Request &req, 128f5c9f8bdSJason M. Bills const std::vector<std::string> ¶ms) override 129f5c9f8bdSJason M. Bills { 130f5c9f8bdSJason M. Bills std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); 131f5c9f8bdSJason M. Bills if (params.size() != 1) 132f5c9f8bdSJason M. Bills { 133f5c9f8bdSJason M. Bills messages::internalError(asyncResp->res); 134f5c9f8bdSJason M. Bills return; 135f5c9f8bdSJason M. Bills } 136f5c9f8bdSJason M. Bills const std::string &device = params[0]; 137f5c9f8bdSJason M. Bills 138f5c9f8bdSJason M. Bills auto getPCIeDeviceCallback = 139f5c9f8bdSJason M. Bills [asyncResp, 140f5c9f8bdSJason M. Bills device](const boost::system::error_code ec, 141f5c9f8bdSJason M. Bills boost::container::flat_map< 142f5c9f8bdSJason M. Bills std::string, sdbusplus::message::variant<std::string>> 143f5c9f8bdSJason M. Bills &pcieDevProperties) { 144f5c9f8bdSJason M. Bills if (ec) 145f5c9f8bdSJason M. Bills { 146f5c9f8bdSJason M. Bills BMCWEB_LOG_DEBUG 147f5c9f8bdSJason M. Bills << "failed to get PCIe Device properties ec: " 148271584abSEd Tanous << ec.value() << ": " << ec.message(); 149f5c9f8bdSJason M. Bills if (ec.value() == 150f5c9f8bdSJason M. Bills boost::system::linux_error::bad_request_descriptor) 151f5c9f8bdSJason M. Bills { 152f5c9f8bdSJason M. Bills messages::resourceNotFound(asyncResp->res, "PCIeDevice", 153f5c9f8bdSJason M. Bills device); 154f5c9f8bdSJason M. Bills } 155f5c9f8bdSJason M. Bills else 156f5c9f8bdSJason M. Bills { 157f5c9f8bdSJason M. Bills messages::internalError(asyncResp->res); 158f5c9f8bdSJason M. Bills } 159f5c9f8bdSJason M. Bills return; 160f5c9f8bdSJason M. Bills } 161f5c9f8bdSJason M. Bills 162f5c9f8bdSJason M. Bills asyncResp->res.jsonValue = { 163dede6a98SJason M. Bills {"@odata.type", "#PCIeDevice.v1_4_0.PCIeDevice"}, 164f5c9f8bdSJason M. Bills {"@odata.context", 165dede6a98SJason M. Bills "/redfish/v1/$metadata#PCIeDevice.v1_4_0.PCIeDevice"}, 166f5c9f8bdSJason M. Bills {"@odata.id", 167f5c9f8bdSJason M. Bills "/redfish/v1/Systems/system/PCIeDevices/" + device}, 168f5c9f8bdSJason M. Bills {"Name", "PCIe Device"}, 169f5c9f8bdSJason M. Bills {"Id", device}}; 170f5c9f8bdSJason M. Bills 171f5c9f8bdSJason M. Bills if (std::string *property = 172f5c9f8bdSJason M. Bills sdbusplus::message::variant_ns::get_if<std::string>( 173f5c9f8bdSJason M. Bills &pcieDevProperties["Manufacturer"]); 174f5c9f8bdSJason M. Bills property) 175f5c9f8bdSJason M. Bills { 176f5c9f8bdSJason M. Bills asyncResp->res.jsonValue["Manufacturer"] = *property; 177f5c9f8bdSJason M. Bills } 178f5c9f8bdSJason M. Bills 179f5c9f8bdSJason M. Bills if (std::string *property = 180f5c9f8bdSJason M. Bills sdbusplus::message::variant_ns::get_if<std::string>( 181f5c9f8bdSJason M. Bills &pcieDevProperties["DeviceType"]); 182f5c9f8bdSJason M. Bills property) 183f5c9f8bdSJason M. Bills { 184f5c9f8bdSJason M. Bills asyncResp->res.jsonValue["DeviceType"] = *property; 185f5c9f8bdSJason M. Bills } 186f5c9f8bdSJason M. Bills 187dede6a98SJason M. Bills asyncResp->res.jsonValue["PCIeFunctions"] = { 188dede6a98SJason M. Bills {"@odata.id", "/redfish/v1/Systems/system/PCIeDevices/" + 189dede6a98SJason M. Bills device + "/PCIeFunctions"}}; 190dede6a98SJason M. Bills }; 191dede6a98SJason M. Bills std::string escapedPath = std::string(pciePath) + "/" + device; 192dede6a98SJason M. Bills dbus::utility::escapePathForDbus(escapedPath); 193dede6a98SJason M. Bills crow::connections::systemBus->async_method_call( 194dede6a98SJason M. Bills std::move(getPCIeDeviceCallback), pcieService, escapedPath, 195dede6a98SJason M. Bills "org.freedesktop.DBus.Properties", "GetAll", pcieDeviceInterface); 196dede6a98SJason M. Bills } 197dede6a98SJason M. Bills }; 198dede6a98SJason M. Bills 199dede6a98SJason M. Bills class SystemPCIeFunctionCollection : public Node 200dede6a98SJason M. Bills { 201dede6a98SJason M. Bills public: 202dede6a98SJason M. Bills template <typename CrowApp> 203dede6a98SJason M. Bills SystemPCIeFunctionCollection(CrowApp &app) : 204dede6a98SJason M. Bills Node(app, "/redfish/v1/Systems/system/PCIeDevices/<str>/PCIeFunctions/", 205dede6a98SJason M. Bills std::string()) 206dede6a98SJason M. Bills { 207dede6a98SJason M. Bills entityPrivileges = { 208dede6a98SJason M. Bills {boost::beast::http::verb::get, {{"Login"}}}, 209dede6a98SJason M. Bills {boost::beast::http::verb::head, {{"Login"}}}, 210dede6a98SJason M. Bills {boost::beast::http::verb::patch, {{"ConfigureManager"}}}, 211dede6a98SJason M. Bills {boost::beast::http::verb::put, {{"ConfigureManager"}}}, 212dede6a98SJason M. Bills {boost::beast::http::verb::delete_, {{"ConfigureManager"}}}, 213dede6a98SJason M. Bills {boost::beast::http::verb::post, {{"ConfigureManager"}}}}; 214dede6a98SJason M. Bills } 215dede6a98SJason M. Bills 216dede6a98SJason M. Bills private: 217dede6a98SJason M. Bills /** 218dede6a98SJason M. Bills * Functions triggers appropriate requests on DBus 219dede6a98SJason M. Bills */ 220dede6a98SJason M. Bills void doGet(crow::Response &res, const crow::Request &req, 221dede6a98SJason M. Bills const std::vector<std::string> ¶ms) override 222dede6a98SJason M. Bills { 223dede6a98SJason M. Bills std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); 224dede6a98SJason M. Bills if (params.size() != 1) 225dede6a98SJason M. Bills { 226dede6a98SJason M. Bills messages::internalError(asyncResp->res); 227dede6a98SJason M. Bills return; 228dede6a98SJason M. Bills } 229dede6a98SJason M. Bills const std::string &device = params[0]; 230dede6a98SJason M. Bills asyncResp->res.jsonValue = { 231dede6a98SJason M. Bills {"@odata.type", "#PCIeFunctionCollection.PCIeFunctionCollection"}, 232dede6a98SJason M. Bills {"@odata.context", 233dede6a98SJason M. Bills "/redfish/v1/" 234dede6a98SJason M. Bills "$metadata#PCIeFunctionCollection.PCIeFunctionCollection"}, 235dede6a98SJason M. Bills {"@odata.id", "/redfish/v1/Systems/system/PCIeDevices/" + device + 236dede6a98SJason M. Bills "/PCIeFunctions"}, 237dede6a98SJason M. Bills {"Name", "PCIe Function Collection"}, 238dede6a98SJason M. Bills {"Description", 239dede6a98SJason M. Bills "Collection of PCIe Functions for PCIe Device " + device}}; 240dede6a98SJason M. Bills 241dede6a98SJason M. Bills auto getPCIeDeviceCallback = 242dede6a98SJason M. Bills [asyncResp, 243dede6a98SJason M. Bills device](const boost::system::error_code ec, 244dede6a98SJason M. Bills boost::container::flat_map< 245dede6a98SJason M. Bills std::string, sdbusplus::message::variant<std::string>> 246dede6a98SJason M. Bills &pcieDevProperties) { 247dede6a98SJason M. Bills if (ec) 248dede6a98SJason M. Bills { 249dede6a98SJason M. Bills BMCWEB_LOG_DEBUG 250dede6a98SJason M. Bills << "failed to get PCIe Device properties ec: " 251dede6a98SJason M. Bills << ec.value() << ": " << ec.message(); 252dede6a98SJason M. Bills if (ec.value() == 253dede6a98SJason M. Bills boost::system::linux_error::bad_request_descriptor) 254dede6a98SJason M. Bills { 255dede6a98SJason M. Bills messages::resourceNotFound(asyncResp->res, "PCIeDevice", 256dede6a98SJason M. Bills device); 257dede6a98SJason M. Bills } 258dede6a98SJason M. Bills else 259dede6a98SJason M. Bills { 260dede6a98SJason M. Bills messages::internalError(asyncResp->res); 261dede6a98SJason M. Bills } 262dede6a98SJason M. Bills return; 263dede6a98SJason M. Bills } 264dede6a98SJason M. Bills 265f5c9f8bdSJason M. Bills nlohmann::json &pcieFunctionList = 266dede6a98SJason M. Bills asyncResp->res.jsonValue["Members"]; 267f5c9f8bdSJason M. Bills pcieFunctionList = nlohmann::json::array(); 268f5c9f8bdSJason M. Bills static constexpr const int maxPciFunctionNum = 8; 269f5c9f8bdSJason M. Bills for (int functionNum = 0; functionNum < maxPciFunctionNum; 270f5c9f8bdSJason M. Bills functionNum++) 271f5c9f8bdSJason M. Bills { 272f5c9f8bdSJason M. Bills // Check if this function exists by looking for a device ID 273f5c9f8bdSJason M. Bills std::string devIDProperty = 274f5c9f8bdSJason M. Bills "Function" + std::to_string(functionNum) + "DeviceId"; 275dede6a98SJason M. Bills std::string *property = 276f5c9f8bdSJason M. Bills sdbusplus::message::variant_ns::get_if<std::string>( 277f5c9f8bdSJason M. Bills &pcieDevProperties[devIDProperty]); 278dede6a98SJason M. Bills if (property && !property->empty()) 279f5c9f8bdSJason M. Bills { 280f5c9f8bdSJason M. Bills pcieFunctionList.push_back( 281f5c9f8bdSJason M. Bills {{"@odata.id", 282f5c9f8bdSJason M. Bills "/redfish/v1/Systems/system/PCIeDevices/" + 283f5c9f8bdSJason M. Bills device + "/PCIeFunctions/" + 284f5c9f8bdSJason M. Bills std::to_string(functionNum)}}); 285f5c9f8bdSJason M. Bills } 286f5c9f8bdSJason M. Bills } 287dede6a98SJason M. Bills asyncResp->res.jsonValue["PCIeFunctions@odata.count"] = 288f5c9f8bdSJason M. Bills pcieFunctionList.size(); 289f5c9f8bdSJason M. Bills }; 290f5c9f8bdSJason M. Bills std::string escapedPath = std::string(pciePath) + "/" + device; 291f5c9f8bdSJason M. Bills dbus::utility::escapePathForDbus(escapedPath); 292f5c9f8bdSJason M. Bills crow::connections::systemBus->async_method_call( 293f5c9f8bdSJason M. Bills std::move(getPCIeDeviceCallback), pcieService, escapedPath, 294f5c9f8bdSJason M. Bills "org.freedesktop.DBus.Properties", "GetAll", pcieDeviceInterface); 295f5c9f8bdSJason M. Bills } 296f5c9f8bdSJason M. Bills }; 297f5c9f8bdSJason M. Bills 298f5c9f8bdSJason M. Bills class SystemPCIeFunction : public Node 299f5c9f8bdSJason M. Bills { 300f5c9f8bdSJason M. Bills public: 301f5c9f8bdSJason M. Bills SystemPCIeFunction(CrowApp &app) : 302f5c9f8bdSJason M. Bills Node( 303f5c9f8bdSJason M. Bills app, 304f5c9f8bdSJason M. Bills "/redfish/v1/Systems/system/PCIeDevices/<str>/PCIeFunctions/<str>/", 305f5c9f8bdSJason M. Bills std::string(), std::string()) 306f5c9f8bdSJason M. Bills { 307f5c9f8bdSJason M. Bills entityPrivileges = { 308f5c9f8bdSJason M. Bills {boost::beast::http::verb::get, {{"Login"}}}, 309f5c9f8bdSJason M. Bills {boost::beast::http::verb::head, {{"Login"}}}, 310f5c9f8bdSJason M. Bills {boost::beast::http::verb::patch, {{"ConfigureManager"}}}, 311f5c9f8bdSJason M. Bills {boost::beast::http::verb::put, {{"ConfigureManager"}}}, 312f5c9f8bdSJason M. Bills {boost::beast::http::verb::delete_, {{"ConfigureManager"}}}, 313f5c9f8bdSJason M. Bills {boost::beast::http::verb::post, {{"ConfigureManager"}}}}; 314f5c9f8bdSJason M. Bills } 315f5c9f8bdSJason M. Bills 316f5c9f8bdSJason M. Bills private: 317f5c9f8bdSJason M. Bills void doGet(crow::Response &res, const crow::Request &req, 318f5c9f8bdSJason M. Bills const std::vector<std::string> ¶ms) override 319f5c9f8bdSJason M. Bills { 320f5c9f8bdSJason M. Bills std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); 321f5c9f8bdSJason M. Bills if (params.size() != 2) 322f5c9f8bdSJason M. Bills { 323f5c9f8bdSJason M. Bills messages::internalError(asyncResp->res); 324f5c9f8bdSJason M. Bills return; 325f5c9f8bdSJason M. Bills } 326f5c9f8bdSJason M. Bills const std::string &device = params[0]; 327f5c9f8bdSJason M. Bills const std::string &function = params[1]; 328f5c9f8bdSJason M. Bills 329f5c9f8bdSJason M. Bills auto getPCIeDeviceCallback = 330f5c9f8bdSJason M. Bills [asyncResp, device, function]( 331f5c9f8bdSJason M. Bills const boost::system::error_code ec, 332f5c9f8bdSJason M. Bills boost::container::flat_map< 333f5c9f8bdSJason M. Bills std::string, sdbusplus::message::variant<std::string>> 334f5c9f8bdSJason M. Bills &pcieDevProperties) { 335f5c9f8bdSJason M. Bills if (ec) 336f5c9f8bdSJason M. Bills { 337f5c9f8bdSJason M. Bills BMCWEB_LOG_DEBUG 338f5c9f8bdSJason M. Bills << "failed to get PCIe Device properties ec: " 339271584abSEd Tanous << ec.value() << ": " << ec.message(); 340f5c9f8bdSJason M. Bills if (ec.value() == 341f5c9f8bdSJason M. Bills boost::system::linux_error::bad_request_descriptor) 342f5c9f8bdSJason M. Bills { 343f5c9f8bdSJason M. Bills messages::resourceNotFound(asyncResp->res, "PCIeDevice", 344f5c9f8bdSJason M. Bills device); 345f5c9f8bdSJason M. Bills } 346f5c9f8bdSJason M. Bills else 347f5c9f8bdSJason M. Bills { 348f5c9f8bdSJason M. Bills messages::internalError(asyncResp->res); 349f5c9f8bdSJason M. Bills } 350f5c9f8bdSJason M. Bills return; 351f5c9f8bdSJason M. Bills } 352f5c9f8bdSJason M. Bills 353f5c9f8bdSJason M. Bills // Check if this function exists by looking for a device ID 354f5c9f8bdSJason M. Bills std::string devIDProperty = "Function" + function + "DeviceId"; 355f5c9f8bdSJason M. Bills if (std::string *property = 356f5c9f8bdSJason M. Bills sdbusplus::message::variant_ns::get_if<std::string>( 357f5c9f8bdSJason M. Bills &pcieDevProperties[devIDProperty]); 358f5c9f8bdSJason M. Bills property && property->empty()) 359f5c9f8bdSJason M. Bills { 360f5c9f8bdSJason M. Bills messages::resourceNotFound(asyncResp->res, "PCIeFunction", 361f5c9f8bdSJason M. Bills function); 362f5c9f8bdSJason M. Bills return; 363f5c9f8bdSJason M. Bills } 364f5c9f8bdSJason M. Bills 365f5c9f8bdSJason M. Bills asyncResp->res.jsonValue = { 366f5c9f8bdSJason M. Bills {"@odata.type", "#PCIeFunction.v1_2_0.PCIeFunction"}, 367f5c9f8bdSJason M. Bills {"@odata.context", 368f5c9f8bdSJason M. Bills "/redfish/v1/$metadata#PCIeFunction.PCIeFunction"}, 369f5c9f8bdSJason M. Bills {"@odata.id", "/redfish/v1/Systems/system/PCIeDevices/" + 370f5c9f8bdSJason M. Bills device + "/PCIeFunctions/" + function}, 371f5c9f8bdSJason M. Bills {"Name", "PCIe Function"}, 372f5c9f8bdSJason M. Bills {"Id", function}, 373f5c9f8bdSJason M. Bills {"FunctionId", std::stoi(function)}, 374f5c9f8bdSJason M. Bills {"Links", 375f5c9f8bdSJason M. Bills {{"PCIeDevice", 376f5c9f8bdSJason M. Bills {{"@odata.id", 377f5c9f8bdSJason M. Bills "/redfish/v1/Systems/system/PCIeDevices/" + 378f5c9f8bdSJason M. Bills device}}}}}}; 379f5c9f8bdSJason M. Bills 380f5c9f8bdSJason M. Bills if (std::string *property = 381f5c9f8bdSJason M. Bills sdbusplus::message::variant_ns::get_if<std::string>( 382f5c9f8bdSJason M. Bills &pcieDevProperties["Function" + function + 383f5c9f8bdSJason M. Bills "DeviceId"]); 384f5c9f8bdSJason M. Bills property) 385f5c9f8bdSJason M. Bills { 386f5c9f8bdSJason M. Bills asyncResp->res.jsonValue["DeviceId"] = *property; 387f5c9f8bdSJason M. Bills } 388f5c9f8bdSJason M. Bills 389f5c9f8bdSJason M. Bills if (std::string *property = 390f5c9f8bdSJason M. Bills sdbusplus::message::variant_ns::get_if<std::string>( 391f5c9f8bdSJason M. Bills &pcieDevProperties["Function" + function + 392f5c9f8bdSJason M. Bills "VendorId"]); 393f5c9f8bdSJason M. Bills property) 394f5c9f8bdSJason M. Bills { 395f5c9f8bdSJason M. Bills asyncResp->res.jsonValue["VendorId"] = *property; 396f5c9f8bdSJason M. Bills } 397f5c9f8bdSJason M. Bills 398f5c9f8bdSJason M. Bills if (std::string *property = 399f5c9f8bdSJason M. Bills sdbusplus::message::variant_ns::get_if<std::string>( 400f5c9f8bdSJason M. Bills &pcieDevProperties["Function" + function + 401f5c9f8bdSJason M. Bills "FunctionType"]); 402f5c9f8bdSJason M. Bills property) 403f5c9f8bdSJason M. Bills { 404f5c9f8bdSJason M. Bills asyncResp->res.jsonValue["FunctionType"] = *property; 405f5c9f8bdSJason M. Bills } 406f5c9f8bdSJason M. Bills 407f5c9f8bdSJason M. Bills if (std::string *property = 408f5c9f8bdSJason M. Bills sdbusplus::message::variant_ns::get_if<std::string>( 409f5c9f8bdSJason M. Bills &pcieDevProperties["Function" + function + 410f5c9f8bdSJason M. Bills "DeviceClass"]); 411f5c9f8bdSJason M. Bills property) 412f5c9f8bdSJason M. Bills { 413f5c9f8bdSJason M. Bills asyncResp->res.jsonValue["DeviceClass"] = *property; 414f5c9f8bdSJason M. Bills } 415f5c9f8bdSJason M. Bills 416f5c9f8bdSJason M. Bills if (std::string *property = 417f5c9f8bdSJason M. Bills sdbusplus::message::variant_ns::get_if<std::string>( 418f5c9f8bdSJason M. Bills &pcieDevProperties["Function" + function + 419f5c9f8bdSJason M. Bills "ClassCode"]); 420f5c9f8bdSJason M. Bills property) 421f5c9f8bdSJason M. Bills { 422f5c9f8bdSJason M. Bills asyncResp->res.jsonValue["ClassCode"] = *property; 423f5c9f8bdSJason M. Bills } 424f5c9f8bdSJason M. Bills 425f5c9f8bdSJason M. Bills if (std::string *property = 426f5c9f8bdSJason M. Bills sdbusplus::message::variant_ns::get_if<std::string>( 427f5c9f8bdSJason M. Bills &pcieDevProperties["Function" + function + 428f5c9f8bdSJason M. Bills "RevisionId"]); 429f5c9f8bdSJason M. Bills property) 430f5c9f8bdSJason M. Bills { 431f5c9f8bdSJason M. Bills asyncResp->res.jsonValue["RevisionId"] = *property; 432f5c9f8bdSJason M. Bills } 433f5c9f8bdSJason M. Bills 434f5c9f8bdSJason M. Bills if (std::string *property = 435f5c9f8bdSJason M. Bills sdbusplus::message::variant_ns::get_if<std::string>( 436f5c9f8bdSJason M. Bills &pcieDevProperties["Function" + function + 437f5c9f8bdSJason M. Bills "SubsystemId"]); 438f5c9f8bdSJason M. Bills property) 439f5c9f8bdSJason M. Bills { 440f5c9f8bdSJason M. Bills asyncResp->res.jsonValue["SubsystemId"] = *property; 441f5c9f8bdSJason M. Bills } 442f5c9f8bdSJason M. Bills 443f5c9f8bdSJason M. Bills if (std::string *property = 444f5c9f8bdSJason M. Bills sdbusplus::message::variant_ns::get_if<std::string>( 445f5c9f8bdSJason M. Bills &pcieDevProperties["Function" + function + 446f5c9f8bdSJason M. Bills "SubsystemVendorId"]); 447f5c9f8bdSJason M. Bills property) 448f5c9f8bdSJason M. Bills { 449f5c9f8bdSJason M. Bills asyncResp->res.jsonValue["SubsystemVendorId"] = *property; 450f5c9f8bdSJason M. Bills } 451f5c9f8bdSJason M. Bills }; 452f5c9f8bdSJason M. Bills std::string escapedPath = std::string(pciePath) + "/" + device; 453f5c9f8bdSJason M. Bills dbus::utility::escapePathForDbus(escapedPath); 454f5c9f8bdSJason M. Bills crow::connections::systemBus->async_method_call( 455f5c9f8bdSJason M. Bills std::move(getPCIeDeviceCallback), pcieService, escapedPath, 456f5c9f8bdSJason M. Bills "org.freedesktop.DBus.Properties", "GetAll", pcieDeviceInterface); 457f5c9f8bdSJason M. Bills } 458f5c9f8bdSJason M. Bills }; 459f5c9f8bdSJason M. Bills 460f5c9f8bdSJason M. Bills } // namespace redfish 461