13179105bSSunny Srivastava #pragma once 23179105bSSunny Srivastava 33179105bSSunny Srivastava #include "app.hpp" 43179105bSSunny Srivastava #include "dbus_utility.hpp" 5a8e884fcSEd Tanous #include "query.hpp" 6a8e884fcSEd Tanous #include "registries/privilege_registry.hpp" 73179105bSSunny Srivastava #include "utils/collection.hpp" 83179105bSSunny Srivastava #include "utils/json_utils.hpp" 93179105bSSunny Srivastava 103179105bSSunny Srivastava #include <boost/system/error_code.hpp> 113179105bSSunny Srivastava 123179105bSSunny Srivastava #include <array> 133179105bSSunny Srivastava #include <functional> 143179105bSSunny Srivastava #include <memory> 153179105bSSunny Srivastava #include <string> 163179105bSSunny Srivastava #include <string_view> 173179105bSSunny Srivastava 183179105bSSunny Srivastava namespace redfish 193179105bSSunny Srivastava { 203179105bSSunny Srivastava 213179105bSSunny Srivastava inline void handleAdapterError(const boost::system::error_code& ec, 223179105bSSunny Srivastava crow::Response& res, 233179105bSSunny Srivastava const std::string& adapterId) 243179105bSSunny Srivastava { 253179105bSSunny Srivastava 263179105bSSunny Srivastava if (ec.value() == boost::system::errc::io_error) 273179105bSSunny Srivastava { 28*53ffeca5SLakshmi Yadlapati messages::resourceNotFound(res, "#FabricAdapter.v1_4_0.FabricAdapter", 293179105bSSunny Srivastava adapterId); 303179105bSSunny Srivastava return; 313179105bSSunny Srivastava } 323179105bSSunny Srivastava 333179105bSSunny Srivastava BMCWEB_LOG_ERROR << "DBus method call failed with error " << ec.value(); 343179105bSSunny Srivastava messages::internalError(res); 353179105bSSunny Srivastava } 363179105bSSunny Srivastava 37*53ffeca5SLakshmi Yadlapati inline void 38*53ffeca5SLakshmi Yadlapati getFabricAdapterLocation(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 39*53ffeca5SLakshmi Yadlapati const std::string& serviceName, 40*53ffeca5SLakshmi Yadlapati const std::string& fabricAdapterPath) 41*53ffeca5SLakshmi Yadlapati { 42*53ffeca5SLakshmi Yadlapati sdbusplus::asio::getProperty<std::string>( 43*53ffeca5SLakshmi Yadlapati *crow::connections::systemBus, serviceName, fabricAdapterPath, 44*53ffeca5SLakshmi Yadlapati "xyz.openbmc_project.Inventory.Decorator.LocationCode", "LocationCode", 45*53ffeca5SLakshmi Yadlapati [aResp](const boost::system::error_code ec, 46*53ffeca5SLakshmi Yadlapati const std::string& property) { 47*53ffeca5SLakshmi Yadlapati if (ec) 48*53ffeca5SLakshmi Yadlapati { 49*53ffeca5SLakshmi Yadlapati if (ec.value() != EBADR) 50*53ffeca5SLakshmi Yadlapati { 51*53ffeca5SLakshmi Yadlapati BMCWEB_LOG_ERROR << "DBUS response error for Location"; 52*53ffeca5SLakshmi Yadlapati messages::internalError(aResp->res); 53*53ffeca5SLakshmi Yadlapati } 54*53ffeca5SLakshmi Yadlapati return; 55*53ffeca5SLakshmi Yadlapati } 56*53ffeca5SLakshmi Yadlapati 57*53ffeca5SLakshmi Yadlapati aResp->res.jsonValue["Location"]["PartLocation"]["ServiceLabel"] = 58*53ffeca5SLakshmi Yadlapati property; 59*53ffeca5SLakshmi Yadlapati }); 60*53ffeca5SLakshmi Yadlapati } 61*53ffeca5SLakshmi Yadlapati 623179105bSSunny Srivastava inline void doAdapterGet(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 633179105bSSunny Srivastava const std::string& systemName, 64*53ffeca5SLakshmi Yadlapati const std::string& adapterId, 65*53ffeca5SLakshmi Yadlapati const std::string& fabricAdapterPath, 66*53ffeca5SLakshmi Yadlapati const std::string& serviceName) 673179105bSSunny Srivastava { 683179105bSSunny Srivastava aResp->res.addHeader( 693179105bSSunny Srivastava boost::beast::http::field::link, 703179105bSSunny Srivastava "</redfish/v1/JsonSchemas/FabricAdapter/FabricAdapter.json>; rel=describedby"); 71*53ffeca5SLakshmi Yadlapati aResp->res.jsonValue["@odata.type"] = "#FabricAdapter.v1_4_0.FabricAdapter"; 723179105bSSunny Srivastava aResp->res.jsonValue["Name"] = "Fabric Adapter"; 733179105bSSunny Srivastava aResp->res.jsonValue["Id"] = adapterId; 743179105bSSunny Srivastava aResp->res.jsonValue["@odata.id"] = crow::utility::urlFromPieces( 753179105bSSunny Srivastava "redfish", "v1", "Systems", systemName, "FabricAdapters", adapterId); 76*53ffeca5SLakshmi Yadlapati 77*53ffeca5SLakshmi Yadlapati getFabricAdapterLocation(aResp, serviceName, fabricAdapterPath); 783179105bSSunny Srivastava } 793179105bSSunny Srivastava 803179105bSSunny Srivastava inline bool checkFabricAdapterId(const std::string& adapterPath, 813179105bSSunny Srivastava const std::string& adapterId) 823179105bSSunny Srivastava { 833179105bSSunny Srivastava std::string fabricAdapterName = 843179105bSSunny Srivastava sdbusplus::message::object_path(adapterPath).filename(); 853179105bSSunny Srivastava 863179105bSSunny Srivastava return !(fabricAdapterName.empty() || fabricAdapterName != adapterId); 873179105bSSunny Srivastava } 883179105bSSunny Srivastava 893179105bSSunny Srivastava inline void getValidFabricAdapterPath( 903179105bSSunny Srivastava const std::string& adapterId, const std::string& systemName, 913179105bSSunny Srivastava const std::shared_ptr<bmcweb::AsyncResp>& aResp, 923179105bSSunny Srivastava std::function<void(const std::string& fabricAdapterPath, 933179105bSSunny Srivastava const std::string& serviceName)>&& callback) 943179105bSSunny Srivastava { 953179105bSSunny Srivastava if (systemName != "system") 963179105bSSunny Srivastava { 973179105bSSunny Srivastava messages::resourceNotFound(aResp->res, "ComputerSystem", systemName); 983179105bSSunny Srivastava return; 993179105bSSunny Srivastava } 1003179105bSSunny Srivastava constexpr std::array<std::string_view, 1> interfaces{ 1013179105bSSunny Srivastava "xyz.openbmc_project.Inventory.Item.FabricAdapter"}; 1023179105bSSunny Srivastava 1033179105bSSunny Srivastava dbus::utility::getSubTree( 1043179105bSSunny Srivastava "/xyz/openbmc_project/inventory", 0, interfaces, 1053179105bSSunny Srivastava [adapterId, aResp, 1063179105bSSunny Srivastava callback](const boost::system::error_code& ec, 1073179105bSSunny Srivastava const dbus::utility::MapperGetSubTreeResponse& subtree) { 1083179105bSSunny Srivastava if (ec) 1093179105bSSunny Srivastava { 1103179105bSSunny Srivastava handleAdapterError(ec, aResp->res, adapterId); 1113179105bSSunny Srivastava return; 1123179105bSSunny Srivastava } 1133179105bSSunny Srivastava for (const auto& [adapterPath, serviceMap] : subtree) 1143179105bSSunny Srivastava { 1153179105bSSunny Srivastava if (checkFabricAdapterId(adapterPath, adapterId)) 1163179105bSSunny Srivastava { 1173179105bSSunny Srivastava callback(adapterPath, serviceMap.begin()->first); 1183179105bSSunny Srivastava return; 1193179105bSSunny Srivastava } 1203179105bSSunny Srivastava } 1213179105bSSunny Srivastava BMCWEB_LOG_WARNING << "Adapter not found"; 1223179105bSSunny Srivastava messages::resourceNotFound(aResp->res, "FabricAdapter", adapterId); 1233179105bSSunny Srivastava }); 1243179105bSSunny Srivastava } 1253179105bSSunny Srivastava 1263179105bSSunny Srivastava inline void 1273179105bSSunny Srivastava handleFabricAdapterGet(App& app, const crow::Request& req, 1283179105bSSunny Srivastava const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1293179105bSSunny Srivastava const std::string& systemName, 1303179105bSSunny Srivastava const std::string& adapterId) 1313179105bSSunny Srivastava { 1323179105bSSunny Srivastava if (!redfish::setUpRedfishRoute(app, req, aResp)) 1333179105bSSunny Srivastava { 1343179105bSSunny Srivastava return; 1353179105bSSunny Srivastava } 1363179105bSSunny Srivastava 1373179105bSSunny Srivastava getValidFabricAdapterPath( 1383179105bSSunny Srivastava adapterId, systemName, aResp, 139*53ffeca5SLakshmi Yadlapati [aResp, systemName, adapterId](const std::string& fabricAdapterPath, 140*53ffeca5SLakshmi Yadlapati const std::string& serviceName) { 141*53ffeca5SLakshmi Yadlapati doAdapterGet(aResp, systemName, adapterId, fabricAdapterPath, 142*53ffeca5SLakshmi Yadlapati serviceName); 1433179105bSSunny Srivastava }); 1443179105bSSunny Srivastava } 1453179105bSSunny Srivastava 1463179105bSSunny Srivastava inline void handleFabricAdapterCollectionGet( 1473179105bSSunny Srivastava crow::App& app, const crow::Request& req, 1483179105bSSunny Srivastava const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1493179105bSSunny Srivastava const std::string& systemName) 1503179105bSSunny Srivastava { 1513179105bSSunny Srivastava if (!redfish::setUpRedfishRoute(app, req, aResp)) 1523179105bSSunny Srivastava { 1533179105bSSunny Srivastava return; 1543179105bSSunny Srivastava } 1553179105bSSunny Srivastava if (systemName != "system") 1563179105bSSunny Srivastava { 1573179105bSSunny Srivastava messages::resourceNotFound(aResp->res, "ComputerSystem", systemName); 1583179105bSSunny Srivastava return; 1593179105bSSunny Srivastava } 1603179105bSSunny Srivastava 1613179105bSSunny Srivastava aResp->res.addHeader( 1623179105bSSunny Srivastava boost::beast::http::field::link, 1633179105bSSunny Srivastava "</redfish/v1/JsonSchemas/FabricAdapterCollection/FabricAdapterCollection.json>; rel=describedby"); 1643179105bSSunny Srivastava aResp->res.jsonValue["@odata.type"] = 1653179105bSSunny Srivastava "#FabricAdapterCollection.FabricAdapterCollection"; 1663179105bSSunny Srivastava aResp->res.jsonValue["Name"] = "Fabric Adapter Collection"; 1673179105bSSunny Srivastava aResp->res.jsonValue["@odata.id"] = crow::utility::urlFromPieces( 1683179105bSSunny Srivastava "redfish", "v1", "Systems", systemName, "FabricAdapters"); 1693179105bSSunny Srivastava 1703179105bSSunny Srivastava constexpr std::array<std::string_view, 1> interfaces{ 1713179105bSSunny Srivastava "xyz.openbmc_project.Inventory.Item.FabricAdapter"}; 1723179105bSSunny Srivastava collection_util::getCollectionMembers( 1733179105bSSunny Srivastava aResp, boost::urls::url("/redfish/v1/Systems/system/FabricAdapters"), 1743179105bSSunny Srivastava interfaces); 1753179105bSSunny Srivastava } 1763179105bSSunny Srivastava 1773179105bSSunny Srivastava inline void handleFabricAdapterCollectionHead( 1783179105bSSunny Srivastava crow::App& app, const crow::Request& req, 1793179105bSSunny Srivastava const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1803179105bSSunny Srivastava const std::string& systemName) 1813179105bSSunny Srivastava { 1823179105bSSunny Srivastava if (!redfish::setUpRedfishRoute(app, req, aResp)) 1833179105bSSunny Srivastava { 1843179105bSSunny Srivastava return; 1853179105bSSunny Srivastava } 1863179105bSSunny Srivastava if (systemName != "system") 1873179105bSSunny Srivastava { 1883179105bSSunny Srivastava messages::resourceNotFound(aResp->res, "ComputerSystem", systemName); 1893179105bSSunny Srivastava return; 1903179105bSSunny Srivastava } 1913179105bSSunny Srivastava aResp->res.addHeader( 1923179105bSSunny Srivastava boost::beast::http::field::link, 1933179105bSSunny Srivastava "</redfish/v1/JsonSchemas/FabricAdapterCollection/FabricAdapterCollection.json>; rel=describedby"); 1943179105bSSunny Srivastava } 1953179105bSSunny Srivastava 1963179105bSSunny Srivastava inline void 1973179105bSSunny Srivastava handleFabricAdapterHead(crow::App& app, const crow::Request& req, 1983179105bSSunny Srivastava const std::shared_ptr<bmcweb::AsyncResp>& aResp, 1993179105bSSunny Srivastava const std::string& systemName, 2003179105bSSunny Srivastava const std::string& adapterId) 2013179105bSSunny Srivastava { 2023179105bSSunny Srivastava if (!redfish::setUpRedfishRoute(app, req, aResp)) 2033179105bSSunny Srivastava { 2043179105bSSunny Srivastava return; 2053179105bSSunny Srivastava } 2063179105bSSunny Srivastava 2073179105bSSunny Srivastava getValidFabricAdapterPath( 2083179105bSSunny Srivastava adapterId, systemName, aResp, 2093179105bSSunny Srivastava [aResp, systemName, adapterId](const std::string&, const std::string&) { 2103179105bSSunny Srivastava aResp->res.addHeader( 2113179105bSSunny Srivastava boost::beast::http::field::link, 2123179105bSSunny Srivastava "</redfish/v1/JsonSchemas/FabricAdapter/FabricAdapter.json>; rel=describedby"); 2133179105bSSunny Srivastava }); 2143179105bSSunny Srivastava } 2153179105bSSunny Srivastava 2163179105bSSunny Srivastava inline void requestRoutesFabricAdapterCollection(App& app) 2173179105bSSunny Srivastava { 2183179105bSSunny Srivastava BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/") 2193179105bSSunny Srivastava .privileges(redfish::privileges::getFabricAdapterCollection) 2203179105bSSunny Srivastava .methods(boost::beast::http::verb::get)( 2213179105bSSunny Srivastava std::bind_front(handleFabricAdapterCollectionGet, std::ref(app))); 2223179105bSSunny Srivastava 2233179105bSSunny Srivastava BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/") 2243179105bSSunny Srivastava .privileges(redfish::privileges::headFabricAdapterCollection) 2253179105bSSunny Srivastava .methods(boost::beast::http::verb::head)( 2263179105bSSunny Srivastava std::bind_front(handleFabricAdapterCollectionHead, std::ref(app))); 2273179105bSSunny Srivastava } 2283179105bSSunny Srivastava 2293179105bSSunny Srivastava inline void requestRoutesFabricAdapters(App& app) 2303179105bSSunny Srivastava { 2313179105bSSunny Srivastava BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/<str>/") 2323179105bSSunny Srivastava .privileges(redfish::privileges::getFabricAdapter) 2333179105bSSunny Srivastava .methods(boost::beast::http::verb::get)( 2343179105bSSunny Srivastava std::bind_front(handleFabricAdapterGet, std::ref(app))); 2353179105bSSunny Srivastava 2363179105bSSunny Srivastava BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/<str>/") 2373179105bSSunny Srivastava .privileges(redfish::privileges::headFabricAdapter) 2383179105bSSunny Srivastava .methods(boost::beast::http::verb::head)( 2393179105bSSunny Srivastava std::bind_front(handleFabricAdapterHead, std::ref(app))); 2403179105bSSunny Srivastava } 2413179105bSSunny Srivastava } // namespace redfish 242