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" 13be1384e3SMyung 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" 19be1384e3SMyung 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> 32be1384e3SMyung 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 194*37937d51SGeorge Liu asyncResp->res.jsonValue["Ports"]["@odata.id"] = 195*37937d51SGeorge Liu boost::urls::format("/redfish/v1/Systems/{}/FabricAdapters/{}/Ports", 196*37937d51SGeorge Liu systemName, adapterId); 197*37937d51SGeorge Liu 198ac106bf6SEd Tanous getFabricAdapterLocation(asyncResp, serviceName, fabricAdapterPath); 199ac106bf6SEd Tanous getFabricAdapterAsset(asyncResp, serviceName, fabricAdapterPath); 200ac106bf6SEd Tanous getFabricAdapterState(asyncResp, serviceName, fabricAdapterPath); 201ac106bf6SEd Tanous getFabricAdapterHealth(asyncResp, serviceName, fabricAdapterPath); 202be1384e3SMyung Bae getLocationIndicatorActive(asyncResp, fabricAdapterPath); 2033179105bSSunny Srivastava } 2043179105bSSunny Srivastava 20578c90203SMyung Bae inline void afterGetValidFabricAdapterPath( 20678c90203SMyung Bae const std::string& adapterId, 20778c90203SMyung Bae std::function<void(const boost::system::error_code&, 20878c90203SMyung Bae const std::string& fabricAdapterPath, 20978c90203SMyung Bae const std::string& serviceName)>& callback, 21078c90203SMyung Bae const boost::system::error_code& ec, 21178c90203SMyung Bae const dbus::utility::MapperGetSubTreeResponse& subtree) 21278c90203SMyung Bae { 21378c90203SMyung Bae std::string fabricAdapterPath; 21478c90203SMyung Bae std::string serviceName; 21578c90203SMyung Bae if (ec) 21678c90203SMyung Bae { 21778c90203SMyung Bae callback(ec, fabricAdapterPath, serviceName); 21878c90203SMyung Bae return; 21978c90203SMyung Bae } 22078c90203SMyung Bae 22178c90203SMyung Bae for (const auto& [adapterPath, serviceMap] : subtree) 2223179105bSSunny Srivastava { 2233179105bSSunny Srivastava std::string fabricAdapterName = 2243179105bSSunny Srivastava sdbusplus::message::object_path(adapterPath).filename(); 22578c90203SMyung Bae if (fabricAdapterName == adapterId) 22678c90203SMyung Bae { 22778c90203SMyung Bae fabricAdapterPath = adapterPath; 22878c90203SMyung Bae serviceName = serviceMap.begin()->first; 22978c90203SMyung Bae break; 23078c90203SMyung Bae } 23178c90203SMyung Bae } 23278c90203SMyung Bae callback(ec, fabricAdapterPath, serviceName); 2333179105bSSunny Srivastava } 2343179105bSSunny Srivastava 2353179105bSSunny Srivastava inline void getValidFabricAdapterPath( 23678c90203SMyung Bae const std::string& adapterId, 23778c90203SMyung Bae std::function<void(const boost::system::error_code& ec, 23878c90203SMyung Bae const std::string& fabricAdapterPath, 2393179105bSSunny Srivastava const std::string& serviceName)>&& callback) 2403179105bSSunny Srivastava { 2413179105bSSunny Srivastava constexpr std::array<std::string_view, 1> interfaces{ 2423179105bSSunny Srivastava "xyz.openbmc_project.Inventory.Item.FabricAdapter"}; 24378c90203SMyung Bae dbus::utility::getSubTree("/xyz/openbmc_project/inventory", 0, interfaces, 24478c90203SMyung Bae std::bind_front(afterGetValidFabricAdapterPath, 24578c90203SMyung Bae adapterId, std::move(callback))); 24678c90203SMyung Bae } 2473179105bSSunny Srivastava 24878c90203SMyung Bae inline void afterHandleFabricAdapterGet( 24978c90203SMyung Bae const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 25078c90203SMyung Bae const std::string& systemName, const std::string& adapterId, 25178c90203SMyung Bae const boost::system::error_code& ec, const std::string& fabricAdapterPath, 25278c90203SMyung Bae const std::string& serviceName) 25378c90203SMyung Bae { 2543179105bSSunny Srivastava if (ec) 2553179105bSSunny Srivastava { 25678c90203SMyung Bae if (ec.value() == boost::system::errc::io_error) 25778c90203SMyung Bae { 25878c90203SMyung Bae messages::resourceNotFound(asyncResp->res, "FabricAdapter", 25978c90203SMyung Bae adapterId); 2603179105bSSunny Srivastava return; 2613179105bSSunny Srivastava } 26278c90203SMyung Bae 26378c90203SMyung Bae BMCWEB_LOG_ERROR("DBus method call failed with error {}", ec.value()); 26478c90203SMyung Bae messages::internalError(asyncResp->res); 2653179105bSSunny Srivastava return; 2663179105bSSunny Srivastava } 26778c90203SMyung Bae if (fabricAdapterPath.empty() || serviceName.empty()) 26878c90203SMyung Bae { 26962598e31SEd Tanous BMCWEB_LOG_WARNING("Adapter not found"); 270ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "FabricAdapter", adapterId); 27178c90203SMyung Bae return; 27278c90203SMyung Bae } 27378c90203SMyung Bae doAdapterGet(asyncResp, systemName, adapterId, fabricAdapterPath, 27478c90203SMyung Bae serviceName); 2753179105bSSunny Srivastava } 2763179105bSSunny Srivastava 277bd79bce8SPatrick Williams inline void handleFabricAdapterGet( 278bd79bce8SPatrick Williams App& app, const crow::Request& req, 279ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 280bd79bce8SPatrick Williams const std::string& systemName, const std::string& adapterId) 2813179105bSSunny Srivastava { 282ac106bf6SEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 2833179105bSSunny Srivastava { 2843179105bSSunny Srivastava return; 2853179105bSSunny Srivastava } 28625b54dbaSEd Tanous if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 2877f3e84a1SEd Tanous { 2887f3e84a1SEd Tanous // Option currently returns no systems. TBD 2897f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 2907f3e84a1SEd Tanous systemName); 2917f3e84a1SEd Tanous return; 2927f3e84a1SEd Tanous } 293253f11b8SEd Tanous if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 29478c90203SMyung Bae { 29578c90203SMyung Bae messages::resourceNotFound(asyncResp->res, "ComputerSystem", 29678c90203SMyung Bae systemName); 29778c90203SMyung Bae return; 29878c90203SMyung Bae } 2993179105bSSunny Srivastava getValidFabricAdapterPath( 30078c90203SMyung Bae adapterId, std::bind_front(afterHandleFabricAdapterGet, asyncResp, 30178c90203SMyung Bae systemName, adapterId)); 3023179105bSSunny Srivastava } 3033179105bSSunny Srivastava 304be1384e3SMyung Bae inline void afterHandleFabricAdapterPatch( 305be1384e3SMyung Bae const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 306be1384e3SMyung Bae const std::string& adapterId, std::optional<bool> locationIndicatorActive, 307be1384e3SMyung Bae const boost::system::error_code& ec, const std::string& fabricAdapterPath, 308be1384e3SMyung Bae const std::string& serviceName) 309be1384e3SMyung Bae { 310be1384e3SMyung Bae if (ec) 311be1384e3SMyung Bae { 312be1384e3SMyung Bae if (ec.value() == boost::system::errc::io_error) 313be1384e3SMyung Bae { 314be1384e3SMyung Bae messages::resourceNotFound(asyncResp->res, "FabricAdapter", 315be1384e3SMyung Bae adapterId); 316be1384e3SMyung Bae return; 317be1384e3SMyung Bae } 318be1384e3SMyung Bae 319be1384e3SMyung Bae BMCWEB_LOG_ERROR("DBus method call failed with error {}", ec.value()); 320be1384e3SMyung Bae messages::internalError(asyncResp->res); 321be1384e3SMyung Bae return; 322be1384e3SMyung Bae } 323be1384e3SMyung Bae if (fabricAdapterPath.empty() || serviceName.empty()) 324be1384e3SMyung Bae { 325be1384e3SMyung Bae BMCWEB_LOG_WARNING("Adapter {} not found", adapterId); 326be1384e3SMyung Bae messages::resourceNotFound(asyncResp->res, "FabricAdapter", adapterId); 327be1384e3SMyung Bae return; 328be1384e3SMyung Bae } 329be1384e3SMyung Bae 330be1384e3SMyung Bae if (locationIndicatorActive) 331be1384e3SMyung Bae { 332be1384e3SMyung Bae setLocationIndicatorActive(asyncResp, fabricAdapterPath, 333be1384e3SMyung Bae *locationIndicatorActive); 334be1384e3SMyung Bae } 335be1384e3SMyung Bae } 336be1384e3SMyung Bae 337be1384e3SMyung Bae inline void handleFabricAdapterPatch( 338be1384e3SMyung Bae App& app, const crow::Request& req, 339be1384e3SMyung Bae const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 340be1384e3SMyung Bae const std::string& systemName, const std::string& adapterId) 341be1384e3SMyung Bae { 342be1384e3SMyung Bae if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 343be1384e3SMyung Bae { 344be1384e3SMyung Bae return; 345be1384e3SMyung Bae } 346be1384e3SMyung Bae if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 347be1384e3SMyung Bae { 348be1384e3SMyung Bae // Option currently returns no systems. TBD 349be1384e3SMyung Bae messages::resourceNotFound(asyncResp->res, "ComputerSystem", 350be1384e3SMyung Bae systemName); 351be1384e3SMyung Bae return; 352be1384e3SMyung Bae } 353be1384e3SMyung Bae if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 354be1384e3SMyung Bae { 355be1384e3SMyung Bae messages::resourceNotFound(asyncResp->res, "ComputerSystem", 356be1384e3SMyung Bae systemName); 357be1384e3SMyung Bae return; 358be1384e3SMyung Bae } 359be1384e3SMyung Bae 360be1384e3SMyung Bae std::optional<bool> locationIndicatorActive; 361be1384e3SMyung Bae 362be1384e3SMyung Bae if (!json_util::readJsonPatch(req, asyncResp->res, 363be1384e3SMyung Bae "LocationIndicatorActive", 364be1384e3SMyung Bae locationIndicatorActive)) 365be1384e3SMyung Bae { 366be1384e3SMyung Bae return; 367be1384e3SMyung Bae } 368be1384e3SMyung Bae 369be1384e3SMyung Bae getValidFabricAdapterPath( 370be1384e3SMyung Bae adapterId, std::bind_front(afterHandleFabricAdapterPatch, asyncResp, 371be1384e3SMyung Bae adapterId, locationIndicatorActive)); 372be1384e3SMyung Bae } 373be1384e3SMyung Bae 3743179105bSSunny Srivastava inline void handleFabricAdapterCollectionGet( 3753179105bSSunny Srivastava crow::App& app, const crow::Request& req, 376ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 3773179105bSSunny Srivastava const std::string& systemName) 3783179105bSSunny Srivastava { 379ac106bf6SEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 3803179105bSSunny Srivastava { 3813179105bSSunny Srivastava return; 3823179105bSSunny Srivastava } 38325b54dbaSEd Tanous if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 3847f3e84a1SEd Tanous { 3857f3e84a1SEd Tanous // Option currently returns no systems. TBD 3867f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 3877f3e84a1SEd Tanous systemName); 3887f3e84a1SEd Tanous return; 3897f3e84a1SEd Tanous } 390253f11b8SEd Tanous if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 3913179105bSSunny Srivastava { 392ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 393ac106bf6SEd Tanous systemName); 3943179105bSSunny Srivastava return; 3953179105bSSunny Srivastava } 3963179105bSSunny Srivastava 397ac106bf6SEd Tanous asyncResp->res.addHeader( 3983179105bSSunny Srivastava boost::beast::http::field::link, 3993179105bSSunny Srivastava "</redfish/v1/JsonSchemas/FabricAdapterCollection/FabricAdapterCollection.json>; rel=describedby"); 400ac106bf6SEd Tanous asyncResp->res.jsonValue["@odata.type"] = 4013179105bSSunny Srivastava "#FabricAdapterCollection.FabricAdapterCollection"; 402ac106bf6SEd Tanous asyncResp->res.jsonValue["Name"] = "Fabric Adapter Collection"; 403ac106bf6SEd Tanous asyncResp->res.jsonValue["@odata.id"] = boost::urls::format( 404ef4c65b7SEd Tanous "/redfish/v1/Systems/{}/FabricAdapters", systemName); 4053179105bSSunny Srivastava 4063179105bSSunny Srivastava constexpr std::array<std::string_view, 1> interfaces{ 4073179105bSSunny Srivastava "xyz.openbmc_project.Inventory.Item.FabricAdapter"}; 4083179105bSSunny Srivastava collection_util::getCollectionMembers( 409ac106bf6SEd Tanous asyncResp, 410253f11b8SEd Tanous boost::urls::format("/redfish/v1/Systems/{}/FabricAdapters", 411253f11b8SEd Tanous BMCWEB_REDFISH_SYSTEM_URI_NAME), 41236b5f1edSLakshmi Yadlapati interfaces, "/xyz/openbmc_project/inventory"); 4133179105bSSunny Srivastava } 4143179105bSSunny Srivastava 4153179105bSSunny Srivastava inline void handleFabricAdapterCollectionHead( 4163179105bSSunny Srivastava crow::App& app, const crow::Request& req, 417ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 4183179105bSSunny Srivastava const std::string& systemName) 4193179105bSSunny Srivastava { 420ac106bf6SEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 4213179105bSSunny Srivastava { 4223179105bSSunny Srivastava return; 4233179105bSSunny Srivastava } 42425b54dbaSEd Tanous if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 4257f3e84a1SEd Tanous { 4267f3e84a1SEd Tanous // Option currently returns no systems. TBD 4277f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 4287f3e84a1SEd Tanous systemName); 4297f3e84a1SEd Tanous return; 4307f3e84a1SEd Tanous } 431253f11b8SEd Tanous if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 4323179105bSSunny Srivastava { 433ac106bf6SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 434ac106bf6SEd Tanous systemName); 4353179105bSSunny Srivastava return; 4363179105bSSunny Srivastava } 437ac106bf6SEd Tanous asyncResp->res.addHeader( 4383179105bSSunny Srivastava boost::beast::http::field::link, 4393179105bSSunny Srivastava "</redfish/v1/JsonSchemas/FabricAdapterCollection/FabricAdapterCollection.json>; rel=describedby"); 4403179105bSSunny Srivastava } 4413179105bSSunny Srivastava 44278c90203SMyung Bae inline void afterHandleFabricAdapterHead( 44378c90203SMyung Bae const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 44478c90203SMyung Bae const std::string& adapterId, const boost::system::error_code& ec, 44578c90203SMyung Bae const std::string& fabricAdapterPath, const std::string& serviceName) 44678c90203SMyung Bae { 44778c90203SMyung Bae if (ec) 44878c90203SMyung Bae { 44978c90203SMyung Bae if (ec.value() == boost::system::errc::io_error) 45078c90203SMyung Bae { 45178c90203SMyung Bae messages::resourceNotFound(asyncResp->res, "FabricAdapter", 45278c90203SMyung Bae adapterId); 45378c90203SMyung Bae return; 45478c90203SMyung Bae } 45578c90203SMyung Bae 45678c90203SMyung Bae BMCWEB_LOG_ERROR("DBus method call failed with error {}", ec.value()); 45778c90203SMyung Bae messages::internalError(asyncResp->res); 45878c90203SMyung Bae return; 45978c90203SMyung Bae } 46078c90203SMyung Bae if (fabricAdapterPath.empty() || serviceName.empty()) 46178c90203SMyung Bae { 46278c90203SMyung Bae BMCWEB_LOG_WARNING("Adapter not found"); 46378c90203SMyung Bae messages::resourceNotFound(asyncResp->res, "FabricAdapter", adapterId); 46478c90203SMyung Bae return; 46578c90203SMyung Bae } 46678c90203SMyung Bae asyncResp->res.addHeader( 46778c90203SMyung Bae boost::beast::http::field::link, 46878c90203SMyung Bae "</redfish/v1/JsonSchemas/FabricAdapter/FabricAdapter.json>; rel=describedby"); 46978c90203SMyung Bae } 47078c90203SMyung Bae 471bd79bce8SPatrick Williams inline void handleFabricAdapterHead( 472bd79bce8SPatrick Williams crow::App& app, const crow::Request& req, 473ac106bf6SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 474bd79bce8SPatrick Williams const std::string& systemName, const std::string& adapterId) 4753179105bSSunny Srivastava { 476ac106bf6SEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 4773179105bSSunny Srivastava { 4783179105bSSunny Srivastava return; 4793179105bSSunny Srivastava } 4803179105bSSunny Srivastava 48125b54dbaSEd Tanous if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 4827f3e84a1SEd Tanous { 4837f3e84a1SEd Tanous // Option currently returns no systems. TBD 4847f3e84a1SEd Tanous messages::resourceNotFound(asyncResp->res, "ComputerSystem", 4857f3e84a1SEd Tanous systemName); 4867f3e84a1SEd Tanous return; 4877f3e84a1SEd Tanous } 488253f11b8SEd Tanous if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 48978c90203SMyung Bae { 49078c90203SMyung Bae messages::resourceNotFound(asyncResp->res, "ComputerSystem", 49178c90203SMyung Bae systemName); 49278c90203SMyung Bae return; 49378c90203SMyung Bae } 49478c90203SMyung Bae getValidFabricAdapterPath( 49578c90203SMyung Bae adapterId, 49678c90203SMyung Bae std::bind_front(afterHandleFabricAdapterHead, asyncResp, adapterId)); 4973179105bSSunny Srivastava } 4983179105bSSunny Srivastava 4993179105bSSunny Srivastava inline void requestRoutesFabricAdapterCollection(App& app) 5003179105bSSunny Srivastava { 5013179105bSSunny Srivastava BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/") 5023179105bSSunny Srivastava .privileges(redfish::privileges::getFabricAdapterCollection) 5033179105bSSunny Srivastava .methods(boost::beast::http::verb::get)( 5043179105bSSunny Srivastava std::bind_front(handleFabricAdapterCollectionGet, std::ref(app))); 5053179105bSSunny Srivastava 5063179105bSSunny Srivastava BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/") 5073179105bSSunny Srivastava .privileges(redfish::privileges::headFabricAdapterCollection) 5083179105bSSunny Srivastava .methods(boost::beast::http::verb::head)( 5093179105bSSunny Srivastava std::bind_front(handleFabricAdapterCollectionHead, std::ref(app))); 5103179105bSSunny Srivastava } 5113179105bSSunny Srivastava 5123179105bSSunny Srivastava inline void requestRoutesFabricAdapters(App& app) 5133179105bSSunny Srivastava { 5143179105bSSunny Srivastava BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/<str>/") 5153179105bSSunny Srivastava .privileges(redfish::privileges::getFabricAdapter) 5163179105bSSunny Srivastava .methods(boost::beast::http::verb::get)( 5173179105bSSunny Srivastava std::bind_front(handleFabricAdapterGet, std::ref(app))); 5183179105bSSunny Srivastava 5193179105bSSunny Srivastava BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/<str>/") 5203179105bSSunny Srivastava .privileges(redfish::privileges::headFabricAdapter) 5213179105bSSunny Srivastava .methods(boost::beast::http::verb::head)( 5223179105bSSunny Srivastava std::bind_front(handleFabricAdapterHead, std::ref(app))); 523be1384e3SMyung Bae 524be1384e3SMyung Bae BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/<str>/") 525be1384e3SMyung Bae .privileges(redfish::privileges::patchFabricAdapter) 526be1384e3SMyung Bae .methods(boost::beast::http::verb::patch)( 527be1384e3SMyung Bae std::bind_front(handleFabricAdapterPatch, std::ref(app))); 5283179105bSSunny Srivastava } 5293179105bSSunny Srivastava } // namespace redfish 530