xref: /openbmc/bmcweb/features/redfish/lib/fabric_adapters.hpp (revision d78572018fc2022091ff8b8eb5a7fef2172ba3d6)
140e9b92eSEd Tanous // SPDX-License-Identifier: Apache-2.0
240e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright OpenBMC Authors
33179105bSSunny Srivastava #pragma once
43179105bSSunny Srivastava 
5*d7857201SEd Tanous #include "bmcweb_config.h"
6*d7857201SEd Tanous 
73179105bSSunny Srivastava #include "app.hpp"
8*d7857201SEd Tanous #include "async_resp.hpp"
93179105bSSunny Srivastava #include "dbus_utility.hpp"
10*d7857201SEd Tanous #include "error_messages.hpp"
11539d8c6bSEd Tanous #include "generated/enums/resource.hpp"
12*d7857201SEd Tanous #include "http_request.hpp"
13*d7857201SEd Tanous #include "logging.hpp"
14a8e884fcSEd Tanous #include "query.hpp"
15a8e884fcSEd Tanous #include "registries/privilege_registry.hpp"
163179105bSSunny Srivastava #include "utils/collection.hpp"
176177a301SLakshmi Yadlapati #include "utils/dbus_utils.hpp"
183179105bSSunny Srivastava 
19*d7857201SEd Tanous #include <asm-generic/errno.h>
20*d7857201SEd Tanous 
21*d7857201SEd Tanous #include <boost/beast/http/field.hpp>
22*d7857201SEd Tanous #include <boost/beast/http/verb.hpp>
233179105bSSunny Srivastava #include <boost/system/error_code.hpp>
24ef4c65b7SEd Tanous #include <boost/url/format.hpp>
256177a301SLakshmi Yadlapati #include <sdbusplus/unpack_properties.hpp>
263179105bSSunny Srivastava 
273179105bSSunny Srivastava #include <array>
283179105bSSunny Srivastava #include <functional>
293179105bSSunny Srivastava #include <memory>
303179105bSSunny Srivastava #include <string>
313179105bSSunny Srivastava #include <string_view>
32*d7857201SEd Tanous #include <utility>
333179105bSSunny Srivastava 
343179105bSSunny Srivastava namespace redfish
353179105bSSunny Srivastava {
363179105bSSunny Srivastava 
37ac106bf6SEd Tanous inline void getFabricAdapterLocation(
38ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
39ac106bf6SEd Tanous     const std::string& serviceName, const std::string& fabricAdapterPath)
4053ffeca5SLakshmi Yadlapati {
41deae6a78SEd Tanous     dbus::utility::getProperty<std::string>(
42deae6a78SEd Tanous         serviceName, fabricAdapterPath,
4353ffeca5SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Decorator.LocationCode", "LocationCode",
44ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
4553ffeca5SLakshmi Yadlapati                     const std::string& property) {
4653ffeca5SLakshmi Yadlapati             if (ec)
4753ffeca5SLakshmi Yadlapati             {
4853ffeca5SLakshmi Yadlapati                 if (ec.value() != EBADR)
4953ffeca5SLakshmi Yadlapati                 {
5062598e31SEd Tanous                     BMCWEB_LOG_ERROR("DBUS response error for Location");
51ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
5253ffeca5SLakshmi Yadlapati                 }
5353ffeca5SLakshmi Yadlapati                 return;
5453ffeca5SLakshmi Yadlapati             }
5553ffeca5SLakshmi Yadlapati 
56bd79bce8SPatrick Williams             asyncResp->res
57bd79bce8SPatrick Williams                 .jsonValue["Location"]["PartLocation"]["ServiceLabel"] =
5853ffeca5SLakshmi Yadlapati                 property;
5953ffeca5SLakshmi Yadlapati         });
6053ffeca5SLakshmi Yadlapati }
6153ffeca5SLakshmi Yadlapati 
62bd79bce8SPatrick Williams inline void getFabricAdapterAsset(
63bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
64bd79bce8SPatrick Williams     const std::string& serviceName, const std::string& fabricAdapterPath)
656369421dSLakshmi Yadlapati {
66deae6a78SEd Tanous     dbus::utility::getAllProperties(
67deae6a78SEd Tanous         serviceName, fabricAdapterPath,
686369421dSLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Decorator.Asset",
69ac106bf6SEd Tanous         [fabricAdapterPath, asyncResp{asyncResp}](
70ac106bf6SEd Tanous             const boost::system::error_code& ec,
716369421dSLakshmi Yadlapati             const dbus::utility::DBusPropertiesMap& propertiesList) {
726369421dSLakshmi Yadlapati             if (ec)
736369421dSLakshmi Yadlapati             {
746369421dSLakshmi Yadlapati                 if (ec.value() != EBADR)
756369421dSLakshmi Yadlapati                 {
7662598e31SEd Tanous                     BMCWEB_LOG_ERROR("DBUS response error for Properties");
77ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
786369421dSLakshmi Yadlapati                 }
796369421dSLakshmi Yadlapati                 return;
806369421dSLakshmi Yadlapati             }
816369421dSLakshmi Yadlapati 
826369421dSLakshmi Yadlapati             const std::string* serialNumber = nullptr;
836369421dSLakshmi Yadlapati             const std::string* model = nullptr;
846369421dSLakshmi Yadlapati             const std::string* partNumber = nullptr;
856369421dSLakshmi Yadlapati             const std::string* sparePartNumber = nullptr;
866369421dSLakshmi Yadlapati 
876369421dSLakshmi Yadlapati             const bool success = sdbusplus::unpackPropertiesNoThrow(
88bd79bce8SPatrick Williams                 dbus_utils::UnpackErrorPrinter(), propertiesList,
89bd79bce8SPatrick Williams                 "SerialNumber", serialNumber, "Model", model, "PartNumber",
90bd79bce8SPatrick Williams                 partNumber, "SparePartNumber", sparePartNumber);
916369421dSLakshmi Yadlapati 
926369421dSLakshmi Yadlapati             if (!success)
936369421dSLakshmi Yadlapati             {
94ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
956369421dSLakshmi Yadlapati                 return;
966369421dSLakshmi Yadlapati             }
976369421dSLakshmi Yadlapati 
986369421dSLakshmi Yadlapati             if (serialNumber != nullptr)
996369421dSLakshmi Yadlapati             {
100ac106bf6SEd Tanous                 asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
1016369421dSLakshmi Yadlapati             }
1026369421dSLakshmi Yadlapati 
1036369421dSLakshmi Yadlapati             if (model != nullptr)
1046369421dSLakshmi Yadlapati             {
105ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Model"] = *model;
1066369421dSLakshmi Yadlapati             }
1076369421dSLakshmi Yadlapati 
1086369421dSLakshmi Yadlapati             if (partNumber != nullptr)
1096369421dSLakshmi Yadlapati             {
110ac106bf6SEd Tanous                 asyncResp->res.jsonValue["PartNumber"] = *partNumber;
1116369421dSLakshmi Yadlapati             }
1126369421dSLakshmi Yadlapati 
1136369421dSLakshmi Yadlapati             if (sparePartNumber != nullptr && !sparePartNumber->empty())
1146369421dSLakshmi Yadlapati             {
115ac106bf6SEd Tanous                 asyncResp->res.jsonValue["SparePartNumber"] = *sparePartNumber;
1166369421dSLakshmi Yadlapati             }
1176369421dSLakshmi Yadlapati         });
1186369421dSLakshmi Yadlapati }
1196369421dSLakshmi Yadlapati 
120bd79bce8SPatrick Williams inline void getFabricAdapterState(
121bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
122bd79bce8SPatrick Williams     const std::string& serviceName, const std::string& fabricAdapterPath)
123cd7af44fSLakshmi Yadlapati {
124deae6a78SEd Tanous     dbus::utility::getProperty<bool>(
125deae6a78SEd Tanous         serviceName, fabricAdapterPath, "xyz.openbmc_project.Inventory.Item",
126deae6a78SEd Tanous         "Present",
127ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec, const bool present) {
128cd7af44fSLakshmi Yadlapati             if (ec)
129cd7af44fSLakshmi Yadlapati             {
130cd7af44fSLakshmi Yadlapati                 if (ec.value() != EBADR)
131cd7af44fSLakshmi Yadlapati                 {
13262598e31SEd Tanous                     BMCWEB_LOG_ERROR("DBUS response error for State");
133ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
134cd7af44fSLakshmi Yadlapati                 }
135cd7af44fSLakshmi Yadlapati                 return;
136cd7af44fSLakshmi Yadlapati             }
137cd7af44fSLakshmi Yadlapati 
138cd7af44fSLakshmi Yadlapati             if (!present)
139cd7af44fSLakshmi Yadlapati             {
140539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
141539d8c6bSEd Tanous                     resource::State::Absent;
142cd7af44fSLakshmi Yadlapati             }
143cd7af44fSLakshmi Yadlapati         });
144cd7af44fSLakshmi Yadlapati }
145cd7af44fSLakshmi Yadlapati 
146bd79bce8SPatrick Williams inline void getFabricAdapterHealth(
147bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
148bd79bce8SPatrick Williams     const std::string& serviceName, const std::string& fabricAdapterPath)
1497da847b6SLakshmi Yadlapati {
150deae6a78SEd Tanous     dbus::utility::getProperty<bool>(
151deae6a78SEd Tanous         serviceName, fabricAdapterPath,
1527da847b6SLakshmi Yadlapati         "xyz.openbmc_project.State.Decorator.OperationalStatus", "Functional",
153ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
154ac106bf6SEd Tanous                     const bool functional) {
1557da847b6SLakshmi Yadlapati             if (ec)
1567da847b6SLakshmi Yadlapati             {
1577da847b6SLakshmi Yadlapati                 if (ec.value() != EBADR)
1587da847b6SLakshmi Yadlapati                 {
15962598e31SEd Tanous                     BMCWEB_LOG_ERROR("DBUS response error for Health");
160ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
1617da847b6SLakshmi Yadlapati                 }
1627da847b6SLakshmi Yadlapati                 return;
1637da847b6SLakshmi Yadlapati             }
1647da847b6SLakshmi Yadlapati 
1657da847b6SLakshmi Yadlapati             if (!functional)
1667da847b6SLakshmi Yadlapati             {
167539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["Health"] =
168539d8c6bSEd Tanous                     resource::Health::Critical;
1697da847b6SLakshmi Yadlapati             }
1707da847b6SLakshmi Yadlapati         });
1717da847b6SLakshmi Yadlapati }
1727da847b6SLakshmi Yadlapati 
173bd79bce8SPatrick Williams inline void doAdapterGet(
174bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
175bd79bce8SPatrick Williams     const std::string& systemName, const std::string& adapterId,
176bd79bce8SPatrick Williams     const std::string& fabricAdapterPath, const std::string& serviceName)
1773179105bSSunny Srivastava {
178ac106bf6SEd Tanous     asyncResp->res.addHeader(
1793179105bSSunny Srivastava         boost::beast::http::field::link,
1803179105bSSunny Srivastava         "</redfish/v1/JsonSchemas/FabricAdapter/FabricAdapter.json>; rel=describedby");
181ac106bf6SEd Tanous     asyncResp->res.jsonValue["@odata.type"] =
182ac106bf6SEd Tanous         "#FabricAdapter.v1_4_0.FabricAdapter";
183ac106bf6SEd Tanous     asyncResp->res.jsonValue["Name"] = "Fabric Adapter";
184ac106bf6SEd Tanous     asyncResp->res.jsonValue["Id"] = adapterId;
185ac106bf6SEd Tanous     asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
186ef4c65b7SEd Tanous         "/redfish/v1/Systems/{}/FabricAdapters/{}", systemName, adapterId);
18753ffeca5SLakshmi Yadlapati 
188539d8c6bSEd Tanous     asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
189539d8c6bSEd Tanous     asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK;
190cd7af44fSLakshmi Yadlapati 
191ac106bf6SEd Tanous     getFabricAdapterLocation(asyncResp, serviceName, fabricAdapterPath);
192ac106bf6SEd Tanous     getFabricAdapterAsset(asyncResp, serviceName, fabricAdapterPath);
193ac106bf6SEd Tanous     getFabricAdapterState(asyncResp, serviceName, fabricAdapterPath);
194ac106bf6SEd Tanous     getFabricAdapterHealth(asyncResp, serviceName, fabricAdapterPath);
1953179105bSSunny Srivastava }
1963179105bSSunny Srivastava 
19778c90203SMyung Bae inline void afterGetValidFabricAdapterPath(
19878c90203SMyung Bae     const std::string& adapterId,
19978c90203SMyung Bae     std::function<void(const boost::system::error_code&,
20078c90203SMyung Bae                        const std::string& fabricAdapterPath,
20178c90203SMyung Bae                        const std::string& serviceName)>& callback,
20278c90203SMyung Bae     const boost::system::error_code& ec,
20378c90203SMyung Bae     const dbus::utility::MapperGetSubTreeResponse& subtree)
20478c90203SMyung Bae {
20578c90203SMyung Bae     std::string fabricAdapterPath;
20678c90203SMyung Bae     std::string serviceName;
20778c90203SMyung Bae     if (ec)
20878c90203SMyung Bae     {
20978c90203SMyung Bae         callback(ec, fabricAdapterPath, serviceName);
21078c90203SMyung Bae         return;
21178c90203SMyung Bae     }
21278c90203SMyung Bae 
21378c90203SMyung Bae     for (const auto& [adapterPath, serviceMap] : subtree)
2143179105bSSunny Srivastava     {
2153179105bSSunny Srivastava         std::string fabricAdapterName =
2163179105bSSunny Srivastava             sdbusplus::message::object_path(adapterPath).filename();
21778c90203SMyung Bae         if (fabricAdapterName == adapterId)
21878c90203SMyung Bae         {
21978c90203SMyung Bae             fabricAdapterPath = adapterPath;
22078c90203SMyung Bae             serviceName = serviceMap.begin()->first;
22178c90203SMyung Bae             break;
22278c90203SMyung Bae         }
22378c90203SMyung Bae     }
22478c90203SMyung Bae     callback(ec, fabricAdapterPath, serviceName);
2253179105bSSunny Srivastava }
2263179105bSSunny Srivastava 
2273179105bSSunny Srivastava inline void getValidFabricAdapterPath(
22878c90203SMyung Bae     const std::string& adapterId,
22978c90203SMyung Bae     std::function<void(const boost::system::error_code& ec,
23078c90203SMyung Bae                        const std::string& fabricAdapterPath,
2313179105bSSunny Srivastava                        const std::string& serviceName)>&& callback)
2323179105bSSunny Srivastava {
2333179105bSSunny Srivastava     constexpr std::array<std::string_view, 1> interfaces{
2343179105bSSunny Srivastava         "xyz.openbmc_project.Inventory.Item.FabricAdapter"};
23578c90203SMyung Bae     dbus::utility::getSubTree("/xyz/openbmc_project/inventory", 0, interfaces,
23678c90203SMyung Bae                               std::bind_front(afterGetValidFabricAdapterPath,
23778c90203SMyung Bae                                               adapterId, std::move(callback)));
23878c90203SMyung Bae }
2393179105bSSunny Srivastava 
24078c90203SMyung Bae inline void afterHandleFabricAdapterGet(
24178c90203SMyung Bae     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
24278c90203SMyung Bae     const std::string& systemName, const std::string& adapterId,
24378c90203SMyung Bae     const boost::system::error_code& ec, const std::string& fabricAdapterPath,
24478c90203SMyung Bae     const std::string& serviceName)
24578c90203SMyung Bae {
2463179105bSSunny Srivastava     if (ec)
2473179105bSSunny Srivastava     {
24878c90203SMyung Bae         if (ec.value() == boost::system::errc::io_error)
24978c90203SMyung Bae         {
25078c90203SMyung Bae             messages::resourceNotFound(asyncResp->res, "FabricAdapter",
25178c90203SMyung Bae                                        adapterId);
2523179105bSSunny Srivastava             return;
2533179105bSSunny Srivastava         }
25478c90203SMyung Bae 
25578c90203SMyung Bae         BMCWEB_LOG_ERROR("DBus method call failed with error {}", ec.value());
25678c90203SMyung Bae         messages::internalError(asyncResp->res);
2573179105bSSunny Srivastava         return;
2583179105bSSunny Srivastava     }
25978c90203SMyung Bae     if (fabricAdapterPath.empty() || serviceName.empty())
26078c90203SMyung Bae     {
26162598e31SEd Tanous         BMCWEB_LOG_WARNING("Adapter not found");
262ac106bf6SEd Tanous         messages::resourceNotFound(asyncResp->res, "FabricAdapter", adapterId);
26378c90203SMyung Bae         return;
26478c90203SMyung Bae     }
26578c90203SMyung Bae     doAdapterGet(asyncResp, systemName, adapterId, fabricAdapterPath,
26678c90203SMyung Bae                  serviceName);
2673179105bSSunny Srivastava }
2683179105bSSunny Srivastava 
269bd79bce8SPatrick Williams inline void handleFabricAdapterGet(
270bd79bce8SPatrick Williams     App& app, const crow::Request& req,
271ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
272bd79bce8SPatrick Williams     const std::string& systemName, const std::string& adapterId)
2733179105bSSunny Srivastava {
274ac106bf6SEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2753179105bSSunny Srivastava     {
2763179105bSSunny Srivastava         return;
2773179105bSSunny Srivastava     }
27825b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
2797f3e84a1SEd Tanous     {
2807f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
2817f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2827f3e84a1SEd Tanous                                    systemName);
2837f3e84a1SEd Tanous         return;
2847f3e84a1SEd Tanous     }
285253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
28678c90203SMyung Bae     {
28778c90203SMyung Bae         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
28878c90203SMyung Bae                                    systemName);
28978c90203SMyung Bae         return;
29078c90203SMyung Bae     }
2913179105bSSunny Srivastava     getValidFabricAdapterPath(
29278c90203SMyung Bae         adapterId, std::bind_front(afterHandleFabricAdapterGet, asyncResp,
29378c90203SMyung Bae                                    systemName, adapterId));
2943179105bSSunny Srivastava }
2953179105bSSunny Srivastava 
2963179105bSSunny Srivastava inline void handleFabricAdapterCollectionGet(
2973179105bSSunny Srivastava     crow::App& app, const crow::Request& req,
298ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2993179105bSSunny Srivastava     const std::string& systemName)
3003179105bSSunny Srivastava {
301ac106bf6SEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3023179105bSSunny Srivastava     {
3033179105bSSunny Srivastava         return;
3043179105bSSunny Srivastava     }
30525b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
3067f3e84a1SEd Tanous     {
3077f3e84a1SEd Tanous         // Option currently returns no systems. TBD
3087f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3097f3e84a1SEd Tanous                                    systemName);
3107f3e84a1SEd Tanous         return;
3117f3e84a1SEd Tanous     }
312253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
3133179105bSSunny Srivastava     {
314ac106bf6SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
315ac106bf6SEd Tanous                                    systemName);
3163179105bSSunny Srivastava         return;
3173179105bSSunny Srivastava     }
3183179105bSSunny Srivastava 
319ac106bf6SEd Tanous     asyncResp->res.addHeader(
3203179105bSSunny Srivastava         boost::beast::http::field::link,
3213179105bSSunny Srivastava         "</redfish/v1/JsonSchemas/FabricAdapterCollection/FabricAdapterCollection.json>; rel=describedby");
322ac106bf6SEd Tanous     asyncResp->res.jsonValue["@odata.type"] =
3233179105bSSunny Srivastava         "#FabricAdapterCollection.FabricAdapterCollection";
324ac106bf6SEd Tanous     asyncResp->res.jsonValue["Name"] = "Fabric Adapter Collection";
325ac106bf6SEd Tanous     asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
326ef4c65b7SEd Tanous         "/redfish/v1/Systems/{}/FabricAdapters", systemName);
3273179105bSSunny Srivastava 
3283179105bSSunny Srivastava     constexpr std::array<std::string_view, 1> interfaces{
3293179105bSSunny Srivastava         "xyz.openbmc_project.Inventory.Item.FabricAdapter"};
3303179105bSSunny Srivastava     collection_util::getCollectionMembers(
331ac106bf6SEd Tanous         asyncResp,
332253f11b8SEd Tanous         boost::urls::format("/redfish/v1/Systems/{}/FabricAdapters",
333253f11b8SEd Tanous                             BMCWEB_REDFISH_SYSTEM_URI_NAME),
33436b5f1edSLakshmi Yadlapati         interfaces, "/xyz/openbmc_project/inventory");
3353179105bSSunny Srivastava }
3363179105bSSunny Srivastava 
3373179105bSSunny Srivastava inline void handleFabricAdapterCollectionHead(
3383179105bSSunny Srivastava     crow::App& app, const crow::Request& req,
339ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3403179105bSSunny Srivastava     const std::string& systemName)
3413179105bSSunny Srivastava {
342ac106bf6SEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3433179105bSSunny Srivastava     {
3443179105bSSunny Srivastava         return;
3453179105bSSunny Srivastava     }
34625b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
3477f3e84a1SEd Tanous     {
3487f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
3497f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3507f3e84a1SEd Tanous                                    systemName);
3517f3e84a1SEd Tanous         return;
3527f3e84a1SEd Tanous     }
353253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
3543179105bSSunny Srivastava     {
355ac106bf6SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
356ac106bf6SEd Tanous                                    systemName);
3573179105bSSunny Srivastava         return;
3583179105bSSunny Srivastava     }
359ac106bf6SEd Tanous     asyncResp->res.addHeader(
3603179105bSSunny Srivastava         boost::beast::http::field::link,
3613179105bSSunny Srivastava         "</redfish/v1/JsonSchemas/FabricAdapterCollection/FabricAdapterCollection.json>; rel=describedby");
3623179105bSSunny Srivastava }
3633179105bSSunny Srivastava 
36478c90203SMyung Bae inline void afterHandleFabricAdapterHead(
36578c90203SMyung Bae     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
36678c90203SMyung Bae     const std::string& adapterId, const boost::system::error_code& ec,
36778c90203SMyung Bae     const std::string& fabricAdapterPath, const std::string& serviceName)
36878c90203SMyung Bae {
36978c90203SMyung Bae     if (ec)
37078c90203SMyung Bae     {
37178c90203SMyung Bae         if (ec.value() == boost::system::errc::io_error)
37278c90203SMyung Bae         {
37378c90203SMyung Bae             messages::resourceNotFound(asyncResp->res, "FabricAdapter",
37478c90203SMyung Bae                                        adapterId);
37578c90203SMyung Bae             return;
37678c90203SMyung Bae         }
37778c90203SMyung Bae 
37878c90203SMyung Bae         BMCWEB_LOG_ERROR("DBus method call failed with error {}", ec.value());
37978c90203SMyung Bae         messages::internalError(asyncResp->res);
38078c90203SMyung Bae         return;
38178c90203SMyung Bae     }
38278c90203SMyung Bae     if (fabricAdapterPath.empty() || serviceName.empty())
38378c90203SMyung Bae     {
38478c90203SMyung Bae         BMCWEB_LOG_WARNING("Adapter not found");
38578c90203SMyung Bae         messages::resourceNotFound(asyncResp->res, "FabricAdapter", adapterId);
38678c90203SMyung Bae         return;
38778c90203SMyung Bae     }
38878c90203SMyung Bae     asyncResp->res.addHeader(
38978c90203SMyung Bae         boost::beast::http::field::link,
39078c90203SMyung Bae         "</redfish/v1/JsonSchemas/FabricAdapter/FabricAdapter.json>; rel=describedby");
39178c90203SMyung Bae }
39278c90203SMyung Bae 
393bd79bce8SPatrick Williams inline void handleFabricAdapterHead(
394bd79bce8SPatrick Williams     crow::App& app, const crow::Request& req,
395ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
396bd79bce8SPatrick Williams     const std::string& systemName, const std::string& adapterId)
3973179105bSSunny Srivastava {
398ac106bf6SEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3993179105bSSunny Srivastava     {
4003179105bSSunny Srivastava         return;
4013179105bSSunny Srivastava     }
4023179105bSSunny Srivastava 
40325b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
4047f3e84a1SEd Tanous     {
4057f3e84a1SEd Tanous         // Option currently returns no systems. TBD
4067f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
4077f3e84a1SEd Tanous                                    systemName);
4087f3e84a1SEd Tanous         return;
4097f3e84a1SEd Tanous     }
410253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
41178c90203SMyung Bae     {
41278c90203SMyung Bae         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
41378c90203SMyung Bae                                    systemName);
41478c90203SMyung Bae         return;
41578c90203SMyung Bae     }
41678c90203SMyung Bae     getValidFabricAdapterPath(
41778c90203SMyung Bae         adapterId,
41878c90203SMyung Bae         std::bind_front(afterHandleFabricAdapterHead, asyncResp, adapterId));
4193179105bSSunny Srivastava }
4203179105bSSunny Srivastava 
4213179105bSSunny Srivastava inline void requestRoutesFabricAdapterCollection(App& app)
4223179105bSSunny Srivastava {
4233179105bSSunny Srivastava     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/")
4243179105bSSunny Srivastava         .privileges(redfish::privileges::getFabricAdapterCollection)
4253179105bSSunny Srivastava         .methods(boost::beast::http::verb::get)(
4263179105bSSunny Srivastava             std::bind_front(handleFabricAdapterCollectionGet, std::ref(app)));
4273179105bSSunny Srivastava 
4283179105bSSunny Srivastava     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/")
4293179105bSSunny Srivastava         .privileges(redfish::privileges::headFabricAdapterCollection)
4303179105bSSunny Srivastava         .methods(boost::beast::http::verb::head)(
4313179105bSSunny Srivastava             std::bind_front(handleFabricAdapterCollectionHead, std::ref(app)));
4323179105bSSunny Srivastava }
4333179105bSSunny Srivastava 
4343179105bSSunny Srivastava inline void requestRoutesFabricAdapters(App& app)
4353179105bSSunny Srivastava {
4363179105bSSunny Srivastava     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/<str>/")
4373179105bSSunny Srivastava         .privileges(redfish::privileges::getFabricAdapter)
4383179105bSSunny Srivastava         .methods(boost::beast::http::verb::get)(
4393179105bSSunny Srivastava             std::bind_front(handleFabricAdapterGet, std::ref(app)));
4403179105bSSunny Srivastava 
4413179105bSSunny Srivastava     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/<str>/")
4423179105bSSunny Srivastava         .privileges(redfish::privileges::headFabricAdapter)
4433179105bSSunny Srivastava         .methods(boost::beast::http::verb::head)(
4443179105bSSunny Srivastava             std::bind_front(handleFabricAdapterHead, std::ref(app)));
4453179105bSSunny Srivastava }
4463179105bSSunny Srivastava } // namespace redfish
447