140e9b92eSEd Tanous // SPDX-License-Identifier: Apache-2.0 240e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright OpenBMC Authors 33179105bSSunny Srivastava #pragma once 43179105bSSunny Srivastava 5d7857201SEd Tanous #include "bmcweb_config.h" 6d7857201SEd Tanous 73179105bSSunny Srivastava #include "app.hpp" 8d7857201SEd Tanous #include "async_resp.hpp" 93179105bSSunny Srivastava #include "dbus_utility.hpp" 10d7857201SEd Tanous #include "error_messages.hpp" 11539d8c6bSEd Tanous #include "generated/enums/resource.hpp" 12d7857201SEd Tanous #include "http_request.hpp" 13*be1384e3SMyung Bae #include "led.hpp" 14d7857201SEd Tanous #include "logging.hpp" 15a8e884fcSEd Tanous #include "query.hpp" 16a8e884fcSEd Tanous #include "registries/privilege_registry.hpp" 173179105bSSunny Srivastava #include "utils/collection.hpp" 186177a301SLakshmi Yadlapati #include "utils/dbus_utils.hpp" 19*be1384e3SMyung Bae #include "utils/json_utils.hpp" 203179105bSSunny Srivastava 21d7857201SEd Tanous #include <asm-generic/errno.h> 22d7857201SEd Tanous 23d7857201SEd Tanous #include <boost/beast/http/field.hpp> 24d7857201SEd Tanous #include <boost/beast/http/verb.hpp> 253179105bSSunny Srivastava #include <boost/system/error_code.hpp> 26ef4c65b7SEd Tanous #include <boost/url/format.hpp> 276177a301SLakshmi Yadlapati #include <sdbusplus/unpack_properties.hpp> 283179105bSSunny Srivastava 293179105bSSunny Srivastava #include <array> 303179105bSSunny Srivastava #include <functional> 313179105bSSunny Srivastava #include <memory> 32*be1384e3SMyung Bae #include <optional> 333179105bSSunny Srivastava #include <string> 343179105bSSunny Srivastava #include <string_view> 35d7857201SEd Tanous #include <utility> 363179105bSSunny Srivastava 373179105bSSunny Srivastava namespace redfish 383179105bSSunny Srivastava { 393179105bSSunny Srivastava 40ac106bf6SEd Tanous inline void getFabricAdapterLocation( 41ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 42ac106bf6SEd Tanous const std::string& serviceName, const std::string& fabricAdapterPath) 4353ffeca5SLakshmi Yadlapati { 44deae6a78SEd Tanous dbus::utility::getProperty<std::string>( 45deae6a78SEd Tanous serviceName, fabricAdapterPath, 4653ffeca5SLakshmi Yadlapati "xyz.openbmc_project.Inventory.Decorator.LocationCode", "LocationCode", 47ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 4853ffeca5SLakshmi Yadlapati const std::string& property) { 4953ffeca5SLakshmi Yadlapati if (ec) 5053ffeca5SLakshmi Yadlapati { 5153ffeca5SLakshmi Yadlapati if (ec.value() != EBADR) 5253ffeca5SLakshmi Yadlapati { 5362598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error for Location"); 54ac106bf6SEd Tanous messages::internalError(asyncResp->res); 5553ffeca5SLakshmi Yadlapati } 5653ffeca5SLakshmi Yadlapati return; 5753ffeca5SLakshmi Yadlapati } 5853ffeca5SLakshmi Yadlapati 59bd79bce8SPatrick Williams asyncResp->res 60bd79bce8SPatrick Williams .jsonValue["Location"]["PartLocation"]["ServiceLabel"] = 6153ffeca5SLakshmi Yadlapati property; 6253ffeca5SLakshmi Yadlapati }); 6353ffeca5SLakshmi Yadlapati } 6453ffeca5SLakshmi Yadlapati 65bd79bce8SPatrick Williams inline void getFabricAdapterAsset( 66bd79bce8SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 67bd79bce8SPatrick Williams const std::string& serviceName, const std::string& fabricAdapterPath) 686369421dSLakshmi Yadlapati { 69deae6a78SEd Tanous dbus::utility::getAllProperties( 70deae6a78SEd Tanous serviceName, fabricAdapterPath, 716369421dSLakshmi Yadlapati "xyz.openbmc_project.Inventory.Decorator.Asset", 72ac106bf6SEd Tanous [fabricAdapterPath, asyncResp{asyncResp}]( 73ac106bf6SEd Tanous const boost::system::error_code& ec, 746369421dSLakshmi Yadlapati const dbus::utility::DBusPropertiesMap& propertiesList) { 756369421dSLakshmi Yadlapati if (ec) 766369421dSLakshmi Yadlapati { 776369421dSLakshmi Yadlapati if (ec.value() != EBADR) 786369421dSLakshmi Yadlapati { 7962598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error for Properties"); 80ac106bf6SEd Tanous messages::internalError(asyncResp->res); 816369421dSLakshmi Yadlapati } 826369421dSLakshmi Yadlapati return; 836369421dSLakshmi Yadlapati } 846369421dSLakshmi Yadlapati 856369421dSLakshmi Yadlapati const std::string* serialNumber = nullptr; 866369421dSLakshmi Yadlapati const std::string* model = nullptr; 876369421dSLakshmi Yadlapati const std::string* partNumber = nullptr; 886369421dSLakshmi Yadlapati const std::string* sparePartNumber = nullptr; 896369421dSLakshmi Yadlapati 906369421dSLakshmi Yadlapati const bool success = sdbusplus::unpackPropertiesNoThrow( 91bd79bce8SPatrick Williams dbus_utils::UnpackErrorPrinter(), propertiesList, 92bd79bce8SPatrick Williams "SerialNumber", serialNumber, "Model", model, "PartNumber", 93bd79bce8SPatrick Williams partNumber, "SparePartNumber", sparePartNumber); 946369421dSLakshmi Yadlapati 956369421dSLakshmi Yadlapati if (!success) 966369421dSLakshmi Yadlapati { 97ac106bf6SEd Tanous messages::internalError(asyncResp->res); 986369421dSLakshmi Yadlapati return; 996369421dSLakshmi Yadlapati } 1006369421dSLakshmi Yadlapati 1016369421dSLakshmi Yadlapati if (serialNumber != nullptr) 1026369421dSLakshmi Yadlapati { 103ac106bf6SEd Tanous asyncResp->res.jsonValue["SerialNumber"] = *serialNumber; 1046369421dSLakshmi Yadlapati } 1056369421dSLakshmi Yadlapati 1066369421dSLakshmi Yadlapati if (model != nullptr) 1076369421dSLakshmi Yadlapati { 108ac106bf6SEd Tanous asyncResp->res.jsonValue["Model"] = *model; 1096369421dSLakshmi Yadlapati } 1106369421dSLakshmi Yadlapati 1116369421dSLakshmi Yadlapati if (partNumber != nullptr) 1126369421dSLakshmi Yadlapati { 113ac106bf6SEd Tanous asyncResp->res.jsonValue["PartNumber"] = *partNumber; 1146369421dSLakshmi Yadlapati } 1156369421dSLakshmi Yadlapati 1166369421dSLakshmi Yadlapati if (sparePartNumber != nullptr && !sparePartNumber->empty()) 1176369421dSLakshmi Yadlapati { 118ac106bf6SEd Tanous asyncResp->res.jsonValue["SparePartNumber"] = *sparePartNumber; 1196369421dSLakshmi Yadlapati } 1206369421dSLakshmi Yadlapati }); 1216369421dSLakshmi Yadlapati } 1226369421dSLakshmi Yadlapati 123bd79bce8SPatrick Williams inline void getFabricAdapterState( 124bd79bce8SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 125bd79bce8SPatrick Williams const std::string& serviceName, const std::string& fabricAdapterPath) 126cd7af44fSLakshmi Yadlapati { 127deae6a78SEd Tanous dbus::utility::getProperty<bool>( 128deae6a78SEd Tanous serviceName, fabricAdapterPath, "xyz.openbmc_project.Inventory.Item", 129deae6a78SEd Tanous "Present", 130ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, const bool present) { 131cd7af44fSLakshmi Yadlapati if (ec) 132cd7af44fSLakshmi Yadlapati { 133cd7af44fSLakshmi Yadlapati if (ec.value() != EBADR) 134cd7af44fSLakshmi Yadlapati { 13562598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error for State"); 136ac106bf6SEd Tanous messages::internalError(asyncResp->res); 137cd7af44fSLakshmi Yadlapati } 138cd7af44fSLakshmi Yadlapati return; 139cd7af44fSLakshmi Yadlapati } 140cd7af44fSLakshmi Yadlapati 141cd7af44fSLakshmi Yadlapati if (!present) 142cd7af44fSLakshmi Yadlapati { 143539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = 144539d8c6bSEd Tanous resource::State::Absent; 145cd7af44fSLakshmi Yadlapati } 146cd7af44fSLakshmi Yadlapati }); 147cd7af44fSLakshmi Yadlapati } 148cd7af44fSLakshmi Yadlapati 149bd79bce8SPatrick Williams inline void getFabricAdapterHealth( 150bd79bce8SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 151bd79bce8SPatrick Williams const std::string& serviceName, const std::string& fabricAdapterPath) 1527da847b6SLakshmi Yadlapati { 153deae6a78SEd Tanous dbus::utility::getProperty<bool>( 154deae6a78SEd Tanous serviceName, fabricAdapterPath, 1557da847b6SLakshmi Yadlapati "xyz.openbmc_project.State.Decorator.OperationalStatus", "Functional", 156ac106bf6SEd Tanous [asyncResp](const boost::system::error_code& ec, 157ac106bf6SEd Tanous const bool functional) { 1587da847b6SLakshmi Yadlapati if (ec) 1597da847b6SLakshmi Yadlapati { 1607da847b6SLakshmi Yadlapati if (ec.value() != EBADR) 1617da847b6SLakshmi Yadlapati { 16262598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error for Health"); 163ac106bf6SEd Tanous messages::internalError(asyncResp->res); 1647da847b6SLakshmi Yadlapati } 1657da847b6SLakshmi Yadlapati return; 1667da847b6SLakshmi Yadlapati } 1677da847b6SLakshmi Yadlapati 1687da847b6SLakshmi Yadlapati if (!functional) 1697da847b6SLakshmi Yadlapati { 170539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["Health"] = 171539d8c6bSEd Tanous resource::Health::Critical; 1727da847b6SLakshmi Yadlapati } 1737da847b6SLakshmi Yadlapati }); 1747da847b6SLakshmi Yadlapati } 1757da847b6SLakshmi Yadlapati 176bd79bce8SPatrick Williams inline void doAdapterGet( 177bd79bce8SPatrick Williams const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 178bd79bce8SPatrick Williams const std::string& systemName, const std::string& adapterId, 179bd79bce8SPatrick Williams const std::string& fabricAdapterPath, const std::string& serviceName) 1803179105bSSunny Srivastava { 181ac106bf6SEd Tanous asyncResp->res.addHeader( 1823179105bSSunny Srivastava boost::beast::http::field::link, 1833179105bSSunny Srivastava "</redfish/v1/JsonSchemas/FabricAdapter/FabricAdapter.json>; rel=describedby"); 184ac106bf6SEd Tanous asyncResp->res.jsonValue["@odata.type"] = 185ac106bf6SEd Tanous "#FabricAdapter.v1_4_0.FabricAdapter"; 186ac106bf6SEd Tanous asyncResp->res.jsonValue["Name"] = "Fabric Adapter"; 187ac106bf6SEd Tanous asyncResp->res.jsonValue["Id"] = adapterId; 188ac106bf6SEd Tanous asyncResp->res.jsonValue["@odata.id"] = boost::urls::format( 189ef4c65b7SEd Tanous "/redfish/v1/Systems/{}/FabricAdapters/{}", systemName, adapterId); 19053ffeca5SLakshmi Yadlapati 191539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled; 192539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK; 193cd7af44fSLakshmi Yadlapati 194ac106bf6SEd Tanous getFabricAdapterLocation(asyncResp, serviceName, fabricAdapterPath); 195ac106bf6SEd Tanous getFabricAdapterAsset(asyncResp, serviceName, fabricAdapterPath); 196ac106bf6SEd Tanous getFabricAdapterState(asyncResp, serviceName, fabricAdapterPath); 197ac106bf6SEd Tanous getFabricAdapterHealth(asyncResp, serviceName, fabricAdapterPath); 198*be1384e3SMyung Bae getLocationIndicatorActive(asyncResp, fabricAdapterPath); 1993179105bSSunny Srivastava } 2003179105bSSunny Srivastava 20178c90203SMyung Bae inline void afterGetValidFabricAdapterPath( 20278c90203SMyung Bae const std::string& adapterId, 20378c90203SMyung Bae std::function<void(const boost::system::error_code&, 20478c90203SMyung Bae const std::string& fabricAdapterPath, 20578c90203SMyung Bae const std::string& serviceName)>& callback, 20678c90203SMyung Bae const boost::system::error_code& ec, 20778c90203SMyung Bae const dbus::utility::MapperGetSubTreeResponse& subtree) 20878c90203SMyung Bae { 20978c90203SMyung Bae std::string fabricAdapterPath; 21078c90203SMyung Bae std::string serviceName; 21178c90203SMyung Bae if (ec) 21278c90203SMyung Bae { 21378c90203SMyung Bae callback(ec, fabricAdapterPath, serviceName); 21478c90203SMyung Bae return; 21578c90203SMyung Bae } 21678c90203SMyung Bae 21778c90203SMyung Bae for (const auto& [adapterPath, serviceMap] : subtree) 2183179105bSSunny Srivastava { 2193179105bSSunny Srivastava std::string fabricAdapterName = 2203179105bSSunny Srivastava sdbusplus::message::object_path(adapterPath).filename(); 22178c90203SMyung Bae if (fabricAdapterName == adapterId) 22278c90203SMyung Bae { 22378c90203SMyung Bae fabricAdapterPath = adapterPath; 22478c90203SMyung Bae serviceName = serviceMap.begin()->first; 22578c90203SMyung Bae break; 22678c90203SMyung Bae } 22778c90203SMyung Bae } 22878c90203SMyung Bae callback(ec, fabricAdapterPath, serviceName); 2293179105bSSunny Srivastava } 2303179105bSSunny Srivastava 2313179105bSSunny Srivastava inline void getValidFabricAdapterPath( 23278c90203SMyung Bae const std::string& adapterId, 23378c90203SMyung Bae std::function<void(const boost::system::error_code& ec, 23478c90203SMyung Bae const std::string& fabricAdapterPath, 2353179105bSSunny Srivastava const std::string& serviceName)>&& callback) 2363179105bSSunny Srivastava { 2373179105bSSunny Srivastava constexpr std::array<std::string_view, 1> interfaces{ 2383179105bSSunny Srivastava "xyz.openbmc_project.Inventory.Item.FabricAdapter"}; 23978c90203SMyung Bae dbus::utility::getSubTree("/xyz/openbmc_project/inventory", 0, interfaces, 24078c90203SMyung Bae std::bind_front(afterGetValidFabricAdapterPath, 24178c90203SMyung Bae adapterId, std::move(callback))); 24278c90203SMyung Bae } 2433179105bSSunny Srivastava 24478c90203SMyung Bae inline void afterHandleFabricAdapterGet( 24578c90203SMyung Bae const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 24678c90203SMyung Bae const std::string& systemName, const std::string& adapterId, 24778c90203SMyung Bae const boost::system::error_code& ec, const std::string& fabricAdapterPath, 24878c90203SMyung Bae const std::string& serviceName) 24978c90203SMyung Bae { 2503179105bSSunny Srivastava if (ec) 2513179105bSSunny Srivastava { 25278c90203SMyung Bae if (ec.value() == boost::system::errc::io_error) 25378c90203SMyung Bae { 25478c90203SMyung Bae messages::resourceNotFound(asyncResp->res, "FabricAdapter", 25578c90203SMyung Bae adapterId); 2563179105bSSunny Srivastava return; 2573179105bSSunny Srivastava } 25878c90203SMyung Bae 25978c90203SMyung Bae BMCWEB_LOG_ERROR("DBus method call failed with error {}", ec.value()); 26078c90203SMyung Bae messages::internalError(asyncResp->res); 2613179105bSSunny Srivastava return; 2623179105bSSunny Srivastava } 26378c90203SMyung Bae if (fabricAdapterPath.empty() || serviceName.empty()) 26478c90203SMyung Bae { 26562598e31SEd Tanous BMCWEB_LOG_WARNING("Adapter not found"); 266ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "FabricAdapter", adapterId); 26778c90203SMyung Bae return; 26878c90203SMyung Bae } 26978c90203SMyung Bae doAdapterGet(asyncResp, systemName, adapterId, fabricAdapterPath, 27078c90203SMyung Bae serviceName); 2713179105bSSunny Srivastava } 2723179105bSSunny Srivastava 273bd79bce8SPatrick Williams inline void handleFabricAdapterGet( 274bd79bce8SPatrick Williams App& app, const crow::Request& req, 275ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 276bd79bce8SPatrick Williams const std::string& systemName, const std::string& adapterId) 2773179105bSSunny Srivastava { 278ac106bf6SEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2793179105bSSunny Srivastava { 2803179105bSSunny Srivastava return; 2813179105bSSunny Srivastava } 28225b54dbaSEd Tanous if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 2837f3e84a1SEd Tanous { 2847f3e84a1SEd Tanous // Option currently returns no systems. TBD 2857f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 2867f3e84a1SEd Tanous systemName); 2877f3e84a1SEd Tanous return; 2887f3e84a1SEd Tanous } 289253f11b8SEd Tanous if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 29078c90203SMyung Bae { 29178c90203SMyung Bae messages::resourceNotFound(asyncResp->res, "ComputerSystem", 29278c90203SMyung Bae systemName); 29378c90203SMyung Bae return; 29478c90203SMyung Bae } 2953179105bSSunny Srivastava getValidFabricAdapterPath( 29678c90203SMyung Bae adapterId, std::bind_front(afterHandleFabricAdapterGet, asyncResp, 29778c90203SMyung Bae systemName, adapterId)); 2983179105bSSunny Srivastava } 2993179105bSSunny Srivastava 300*be1384e3SMyung Bae inline void afterHandleFabricAdapterPatch( 301*be1384e3SMyung Bae const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 302*be1384e3SMyung Bae const std::string& adapterId, std::optional<bool> locationIndicatorActive, 303*be1384e3SMyung Bae const boost::system::error_code& ec, const std::string& fabricAdapterPath, 304*be1384e3SMyung Bae const std::string& serviceName) 305*be1384e3SMyung Bae { 306*be1384e3SMyung Bae if (ec) 307*be1384e3SMyung Bae { 308*be1384e3SMyung Bae if (ec.value() == boost::system::errc::io_error) 309*be1384e3SMyung Bae { 310*be1384e3SMyung Bae messages::resourceNotFound(asyncResp->res, "FabricAdapter", 311*be1384e3SMyung Bae adapterId); 312*be1384e3SMyung Bae return; 313*be1384e3SMyung Bae } 314*be1384e3SMyung Bae 315*be1384e3SMyung Bae BMCWEB_LOG_ERROR("DBus method call failed with error {}", ec.value()); 316*be1384e3SMyung Bae messages::internalError(asyncResp->res); 317*be1384e3SMyung Bae return; 318*be1384e3SMyung Bae } 319*be1384e3SMyung Bae if (fabricAdapterPath.empty() || serviceName.empty()) 320*be1384e3SMyung Bae { 321*be1384e3SMyung Bae BMCWEB_LOG_WARNING("Adapter {} not found", adapterId); 322*be1384e3SMyung Bae messages::resourceNotFound(asyncResp->res, "FabricAdapter", adapterId); 323*be1384e3SMyung Bae return; 324*be1384e3SMyung Bae } 325*be1384e3SMyung Bae 326*be1384e3SMyung Bae if (locationIndicatorActive) 327*be1384e3SMyung Bae { 328*be1384e3SMyung Bae setLocationIndicatorActive(asyncResp, fabricAdapterPath, 329*be1384e3SMyung Bae *locationIndicatorActive); 330*be1384e3SMyung Bae } 331*be1384e3SMyung Bae } 332*be1384e3SMyung Bae 333*be1384e3SMyung Bae inline void handleFabricAdapterPatch( 334*be1384e3SMyung Bae App& app, const crow::Request& req, 335*be1384e3SMyung Bae const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 336*be1384e3SMyung Bae const std::string& systemName, const std::string& adapterId) 337*be1384e3SMyung Bae { 338*be1384e3SMyung Bae if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 339*be1384e3SMyung Bae { 340*be1384e3SMyung Bae return; 341*be1384e3SMyung Bae } 342*be1384e3SMyung Bae if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 343*be1384e3SMyung Bae { 344*be1384e3SMyung Bae // Option currently returns no systems. TBD 345*be1384e3SMyung Bae messages::resourceNotFound(asyncResp->res, "ComputerSystem", 346*be1384e3SMyung Bae systemName); 347*be1384e3SMyung Bae return; 348*be1384e3SMyung Bae } 349*be1384e3SMyung Bae if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 350*be1384e3SMyung Bae { 351*be1384e3SMyung Bae messages::resourceNotFound(asyncResp->res, "ComputerSystem", 352*be1384e3SMyung Bae systemName); 353*be1384e3SMyung Bae return; 354*be1384e3SMyung Bae } 355*be1384e3SMyung Bae 356*be1384e3SMyung Bae std::optional<bool> locationIndicatorActive; 357*be1384e3SMyung Bae 358*be1384e3SMyung Bae if (!json_util::readJsonPatch(req, asyncResp->res, 359*be1384e3SMyung Bae "LocationIndicatorActive", 360*be1384e3SMyung Bae locationIndicatorActive)) 361*be1384e3SMyung Bae { 362*be1384e3SMyung Bae return; 363*be1384e3SMyung Bae } 364*be1384e3SMyung Bae 365*be1384e3SMyung Bae getValidFabricAdapterPath( 366*be1384e3SMyung Bae adapterId, std::bind_front(afterHandleFabricAdapterPatch, asyncResp, 367*be1384e3SMyung Bae adapterId, locationIndicatorActive)); 368*be1384e3SMyung Bae } 369*be1384e3SMyung Bae 3703179105bSSunny Srivastava inline void handleFabricAdapterCollectionGet( 3713179105bSSunny Srivastava crow::App& app, const crow::Request& req, 372ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3733179105bSSunny Srivastava const std::string& systemName) 3743179105bSSunny Srivastava { 375ac106bf6SEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 3763179105bSSunny Srivastava { 3773179105bSSunny Srivastava return; 3783179105bSSunny Srivastava } 37925b54dbaSEd Tanous if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 3807f3e84a1SEd Tanous { 3817f3e84a1SEd Tanous // Option currently returns no systems. TBD 3827f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 3837f3e84a1SEd Tanous systemName); 3847f3e84a1SEd Tanous return; 3857f3e84a1SEd Tanous } 386253f11b8SEd Tanous if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 3873179105bSSunny Srivastava { 388ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 389ac106bf6SEd Tanous systemName); 3903179105bSSunny Srivastava return; 3913179105bSSunny Srivastava } 3923179105bSSunny Srivastava 393ac106bf6SEd Tanous asyncResp->res.addHeader( 3943179105bSSunny Srivastava boost::beast::http::field::link, 3953179105bSSunny Srivastava "</redfish/v1/JsonSchemas/FabricAdapterCollection/FabricAdapterCollection.json>; rel=describedby"); 396ac106bf6SEd Tanous asyncResp->res.jsonValue["@odata.type"] = 3973179105bSSunny Srivastava "#FabricAdapterCollection.FabricAdapterCollection"; 398ac106bf6SEd Tanous asyncResp->res.jsonValue["Name"] = "Fabric Adapter Collection"; 399ac106bf6SEd Tanous asyncResp->res.jsonValue["@odata.id"] = boost::urls::format( 400ef4c65b7SEd Tanous "/redfish/v1/Systems/{}/FabricAdapters", systemName); 4013179105bSSunny Srivastava 4023179105bSSunny Srivastava constexpr std::array<std::string_view, 1> interfaces{ 4033179105bSSunny Srivastava "xyz.openbmc_project.Inventory.Item.FabricAdapter"}; 4043179105bSSunny Srivastava collection_util::getCollectionMembers( 405ac106bf6SEd Tanous asyncResp, 406253f11b8SEd Tanous boost::urls::format("/redfish/v1/Systems/{}/FabricAdapters", 407253f11b8SEd Tanous BMCWEB_REDFISH_SYSTEM_URI_NAME), 40836b5f1edSLakshmi Yadlapati interfaces, "/xyz/openbmc_project/inventory"); 4093179105bSSunny Srivastava } 4103179105bSSunny Srivastava 4113179105bSSunny Srivastava inline void handleFabricAdapterCollectionHead( 4123179105bSSunny Srivastava crow::App& app, const crow::Request& req, 413ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 4143179105bSSunny Srivastava const std::string& systemName) 4153179105bSSunny Srivastava { 416ac106bf6SEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 4173179105bSSunny Srivastava { 4183179105bSSunny Srivastava return; 4193179105bSSunny Srivastava } 42025b54dbaSEd Tanous if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 4217f3e84a1SEd Tanous { 4227f3e84a1SEd Tanous // Option currently returns no systems. TBD 4237f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 4247f3e84a1SEd Tanous systemName); 4257f3e84a1SEd Tanous return; 4267f3e84a1SEd Tanous } 427253f11b8SEd Tanous if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 4283179105bSSunny Srivastava { 429ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 430ac106bf6SEd Tanous systemName); 4313179105bSSunny Srivastava return; 4323179105bSSunny Srivastava } 433ac106bf6SEd Tanous asyncResp->res.addHeader( 4343179105bSSunny Srivastava boost::beast::http::field::link, 4353179105bSSunny Srivastava "</redfish/v1/JsonSchemas/FabricAdapterCollection/FabricAdapterCollection.json>; rel=describedby"); 4363179105bSSunny Srivastava } 4373179105bSSunny Srivastava 43878c90203SMyung Bae inline void afterHandleFabricAdapterHead( 43978c90203SMyung Bae const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 44078c90203SMyung Bae const std::string& adapterId, const boost::system::error_code& ec, 44178c90203SMyung Bae const std::string& fabricAdapterPath, const std::string& serviceName) 44278c90203SMyung Bae { 44378c90203SMyung Bae if (ec) 44478c90203SMyung Bae { 44578c90203SMyung Bae if (ec.value() == boost::system::errc::io_error) 44678c90203SMyung Bae { 44778c90203SMyung Bae messages::resourceNotFound(asyncResp->res, "FabricAdapter", 44878c90203SMyung Bae adapterId); 44978c90203SMyung Bae return; 45078c90203SMyung Bae } 45178c90203SMyung Bae 45278c90203SMyung Bae BMCWEB_LOG_ERROR("DBus method call failed with error {}", ec.value()); 45378c90203SMyung Bae messages::internalError(asyncResp->res); 45478c90203SMyung Bae return; 45578c90203SMyung Bae } 45678c90203SMyung Bae if (fabricAdapterPath.empty() || serviceName.empty()) 45778c90203SMyung Bae { 45878c90203SMyung Bae BMCWEB_LOG_WARNING("Adapter not found"); 45978c90203SMyung Bae messages::resourceNotFound(asyncResp->res, "FabricAdapter", adapterId); 46078c90203SMyung Bae return; 46178c90203SMyung Bae } 46278c90203SMyung Bae asyncResp->res.addHeader( 46378c90203SMyung Bae boost::beast::http::field::link, 46478c90203SMyung Bae "</redfish/v1/JsonSchemas/FabricAdapter/FabricAdapter.json>; rel=describedby"); 46578c90203SMyung Bae } 46678c90203SMyung Bae 467bd79bce8SPatrick Williams inline void handleFabricAdapterHead( 468bd79bce8SPatrick Williams crow::App& app, const crow::Request& req, 469ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 470bd79bce8SPatrick Williams const std::string& systemName, const std::string& adapterId) 4713179105bSSunny Srivastava { 472ac106bf6SEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 4733179105bSSunny Srivastava { 4743179105bSSunny Srivastava return; 4753179105bSSunny Srivastava } 4763179105bSSunny Srivastava 47725b54dbaSEd Tanous if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 4787f3e84a1SEd Tanous { 4797f3e84a1SEd Tanous // Option currently returns no systems. TBD 4807f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 4817f3e84a1SEd Tanous systemName); 4827f3e84a1SEd Tanous return; 4837f3e84a1SEd Tanous } 484253f11b8SEd Tanous if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 48578c90203SMyung Bae { 48678c90203SMyung Bae messages::resourceNotFound(asyncResp->res, "ComputerSystem", 48778c90203SMyung Bae systemName); 48878c90203SMyung Bae return; 48978c90203SMyung Bae } 49078c90203SMyung Bae getValidFabricAdapterPath( 49178c90203SMyung Bae adapterId, 49278c90203SMyung Bae std::bind_front(afterHandleFabricAdapterHead, asyncResp, adapterId)); 4933179105bSSunny Srivastava } 4943179105bSSunny Srivastava 4953179105bSSunny Srivastava inline void requestRoutesFabricAdapterCollection(App& app) 4963179105bSSunny Srivastava { 4973179105bSSunny Srivastava BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/") 4983179105bSSunny Srivastava .privileges(redfish::privileges::getFabricAdapterCollection) 4993179105bSSunny Srivastava .methods(boost::beast::http::verb::get)( 5003179105bSSunny Srivastava std::bind_front(handleFabricAdapterCollectionGet, std::ref(app))); 5013179105bSSunny Srivastava 5023179105bSSunny Srivastava BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/") 5033179105bSSunny Srivastava .privileges(redfish::privileges::headFabricAdapterCollection) 5043179105bSSunny Srivastava .methods(boost::beast::http::verb::head)( 5053179105bSSunny Srivastava std::bind_front(handleFabricAdapterCollectionHead, std::ref(app))); 5063179105bSSunny Srivastava } 5073179105bSSunny Srivastava 5083179105bSSunny Srivastava inline void requestRoutesFabricAdapters(App& app) 5093179105bSSunny Srivastava { 5103179105bSSunny Srivastava BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/<str>/") 5113179105bSSunny Srivastava .privileges(redfish::privileges::getFabricAdapter) 5123179105bSSunny Srivastava .methods(boost::beast::http::verb::get)( 5133179105bSSunny Srivastava std::bind_front(handleFabricAdapterGet, std::ref(app))); 5143179105bSSunny Srivastava 5153179105bSSunny Srivastava BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/<str>/") 5163179105bSSunny Srivastava .privileges(redfish::privileges::headFabricAdapter) 5173179105bSSunny Srivastava .methods(boost::beast::http::verb::head)( 5183179105bSSunny Srivastava std::bind_front(handleFabricAdapterHead, std::ref(app))); 519*be1384e3SMyung Bae 520*be1384e3SMyung Bae BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/<str>/") 521*be1384e3SMyung Bae .privileges(redfish::privileges::patchFabricAdapter) 522*be1384e3SMyung Bae .methods(boost::beast::http::verb::patch)( 523*be1384e3SMyung Bae std::bind_front(handleFabricAdapterPatch, std::ref(app))); 5243179105bSSunny Srivastava } 5253179105bSSunny Srivastava } // namespace redfish 526