xref: /openbmc/bmcweb/features/redfish/lib/fabric_adapters.hpp (revision 539d8c6bc399e516d39bcaa18262cf206f4c1035)
13179105bSSunny Srivastava #pragma once
23179105bSSunny Srivastava 
33179105bSSunny Srivastava #include "app.hpp"
43179105bSSunny Srivastava #include "dbus_utility.hpp"
5*539d8c6bSEd Tanous #include "generated/enums/resource.hpp"
6a8e884fcSEd Tanous #include "query.hpp"
7a8e884fcSEd Tanous #include "registries/privilege_registry.hpp"
83179105bSSunny Srivastava #include "utils/collection.hpp"
96177a301SLakshmi Yadlapati #include "utils/dbus_utils.hpp"
103179105bSSunny Srivastava #include "utils/json_utils.hpp"
113179105bSSunny Srivastava 
123179105bSSunny Srivastava #include <boost/system/error_code.hpp>
13ef4c65b7SEd Tanous #include <boost/url/format.hpp>
14f05e9169SGunnar Mills #include <sdbusplus/asio/property.hpp>
156177a301SLakshmi Yadlapati #include <sdbusplus/unpack_properties.hpp>
163179105bSSunny Srivastava 
173179105bSSunny Srivastava #include <array>
183179105bSSunny Srivastava #include <functional>
193179105bSSunny Srivastava #include <memory>
2078c90203SMyung Bae #include <optional>
213179105bSSunny Srivastava #include <string>
223179105bSSunny Srivastava #include <string_view>
233179105bSSunny Srivastava 
243179105bSSunny Srivastava namespace redfish
253179105bSSunny Srivastava {
263179105bSSunny Srivastava 
27ac106bf6SEd Tanous inline void getFabricAdapterLocation(
28ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
29ac106bf6SEd Tanous     const std::string& serviceName, const std::string& fabricAdapterPath)
3053ffeca5SLakshmi Yadlapati {
3153ffeca5SLakshmi Yadlapati     sdbusplus::asio::getProperty<std::string>(
3253ffeca5SLakshmi Yadlapati         *crow::connections::systemBus, serviceName, fabricAdapterPath,
3353ffeca5SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Decorator.LocationCode", "LocationCode",
34ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
3553ffeca5SLakshmi Yadlapati                     const std::string& property) {
3653ffeca5SLakshmi Yadlapati         if (ec)
3753ffeca5SLakshmi Yadlapati         {
3853ffeca5SLakshmi Yadlapati             if (ec.value() != EBADR)
3953ffeca5SLakshmi Yadlapati             {
4062598e31SEd Tanous                 BMCWEB_LOG_ERROR("DBUS response error for Location");
41ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
4253ffeca5SLakshmi Yadlapati             }
4353ffeca5SLakshmi Yadlapati             return;
4453ffeca5SLakshmi Yadlapati         }
4553ffeca5SLakshmi Yadlapati 
46ac106bf6SEd Tanous         asyncResp->res.jsonValue["Location"]["PartLocation"]["ServiceLabel"] =
4753ffeca5SLakshmi Yadlapati             property;
4853ffeca5SLakshmi Yadlapati     });
4953ffeca5SLakshmi Yadlapati }
5053ffeca5SLakshmi Yadlapati 
516369421dSLakshmi Yadlapati inline void
52ac106bf6SEd Tanous     getFabricAdapterAsset(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
536369421dSLakshmi Yadlapati                           const std::string& serviceName,
546369421dSLakshmi Yadlapati                           const std::string& fabricAdapterPath)
556369421dSLakshmi Yadlapati {
566369421dSLakshmi Yadlapati     sdbusplus::asio::getAllProperties(
576369421dSLakshmi Yadlapati         *crow::connections::systemBus, serviceName, fabricAdapterPath,
586369421dSLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Decorator.Asset",
59ac106bf6SEd Tanous         [fabricAdapterPath, asyncResp{asyncResp}](
60ac106bf6SEd Tanous             const boost::system::error_code& ec,
616369421dSLakshmi Yadlapati             const dbus::utility::DBusPropertiesMap& propertiesList) {
626369421dSLakshmi Yadlapati         if (ec)
636369421dSLakshmi Yadlapati         {
646369421dSLakshmi Yadlapati             if (ec.value() != EBADR)
656369421dSLakshmi Yadlapati             {
6662598e31SEd Tanous                 BMCWEB_LOG_ERROR("DBUS response error for Properties");
67ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
686369421dSLakshmi Yadlapati             }
696369421dSLakshmi Yadlapati             return;
706369421dSLakshmi Yadlapati         }
716369421dSLakshmi Yadlapati 
726369421dSLakshmi Yadlapati         const std::string* serialNumber = nullptr;
736369421dSLakshmi Yadlapati         const std::string* model = nullptr;
746369421dSLakshmi Yadlapati         const std::string* partNumber = nullptr;
756369421dSLakshmi Yadlapati         const std::string* sparePartNumber = nullptr;
766369421dSLakshmi Yadlapati 
776369421dSLakshmi Yadlapati         const bool success = sdbusplus::unpackPropertiesNoThrow(
786369421dSLakshmi Yadlapati             dbus_utils::UnpackErrorPrinter(), propertiesList, "SerialNumber",
796369421dSLakshmi Yadlapati             serialNumber, "Model", model, "PartNumber", partNumber,
806369421dSLakshmi Yadlapati             "SparePartNumber", sparePartNumber);
816369421dSLakshmi Yadlapati 
826369421dSLakshmi Yadlapati         if (!success)
836369421dSLakshmi Yadlapati         {
84ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
856369421dSLakshmi Yadlapati             return;
866369421dSLakshmi Yadlapati         }
876369421dSLakshmi Yadlapati 
886369421dSLakshmi Yadlapati         if (serialNumber != nullptr)
896369421dSLakshmi Yadlapati         {
90ac106bf6SEd Tanous             asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
916369421dSLakshmi Yadlapati         }
926369421dSLakshmi Yadlapati 
936369421dSLakshmi Yadlapati         if (model != nullptr)
946369421dSLakshmi Yadlapati         {
95ac106bf6SEd Tanous             asyncResp->res.jsonValue["Model"] = *model;
966369421dSLakshmi Yadlapati         }
976369421dSLakshmi Yadlapati 
986369421dSLakshmi Yadlapati         if (partNumber != nullptr)
996369421dSLakshmi Yadlapati         {
100ac106bf6SEd Tanous             asyncResp->res.jsonValue["PartNumber"] = *partNumber;
1016369421dSLakshmi Yadlapati         }
1026369421dSLakshmi Yadlapati 
1036369421dSLakshmi Yadlapati         if (sparePartNumber != nullptr && !sparePartNumber->empty())
1046369421dSLakshmi Yadlapati         {
105ac106bf6SEd Tanous             asyncResp->res.jsonValue["SparePartNumber"] = *sparePartNumber;
1066369421dSLakshmi Yadlapati         }
1076369421dSLakshmi Yadlapati     });
1086369421dSLakshmi Yadlapati }
1096369421dSLakshmi Yadlapati 
110cd7af44fSLakshmi Yadlapati inline void
111ac106bf6SEd Tanous     getFabricAdapterState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
112cd7af44fSLakshmi Yadlapati                           const std::string& serviceName,
113cd7af44fSLakshmi Yadlapati                           const std::string& fabricAdapterPath)
114cd7af44fSLakshmi Yadlapati {
115cd7af44fSLakshmi Yadlapati     sdbusplus::asio::getProperty<bool>(
116cd7af44fSLakshmi Yadlapati         *crow::connections::systemBus, serviceName, fabricAdapterPath,
117cd7af44fSLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Item", "Present",
118ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec, const bool present) {
119cd7af44fSLakshmi Yadlapati         if (ec)
120cd7af44fSLakshmi Yadlapati         {
121cd7af44fSLakshmi Yadlapati             if (ec.value() != EBADR)
122cd7af44fSLakshmi Yadlapati             {
12362598e31SEd Tanous                 BMCWEB_LOG_ERROR("DBUS response error for State");
124ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
125cd7af44fSLakshmi Yadlapati             }
126cd7af44fSLakshmi Yadlapati             return;
127cd7af44fSLakshmi Yadlapati         }
128cd7af44fSLakshmi Yadlapati 
129cd7af44fSLakshmi Yadlapati         if (!present)
130cd7af44fSLakshmi Yadlapati         {
131*539d8c6bSEd Tanous             asyncResp->res.jsonValue["Status"]["State"] =
132*539d8c6bSEd Tanous                 resource::State::Absent;
133cd7af44fSLakshmi Yadlapati         }
134cd7af44fSLakshmi Yadlapati     });
135cd7af44fSLakshmi Yadlapati }
136cd7af44fSLakshmi Yadlapati 
1377da847b6SLakshmi Yadlapati inline void
138ac106bf6SEd Tanous     getFabricAdapterHealth(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1397da847b6SLakshmi Yadlapati                            const std::string& serviceName,
1407da847b6SLakshmi Yadlapati                            const std::string& fabricAdapterPath)
1417da847b6SLakshmi Yadlapati {
1427da847b6SLakshmi Yadlapati     sdbusplus::asio::getProperty<bool>(
1437da847b6SLakshmi Yadlapati         *crow::connections::systemBus, serviceName, fabricAdapterPath,
1447da847b6SLakshmi Yadlapati         "xyz.openbmc_project.State.Decorator.OperationalStatus", "Functional",
145ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
146ac106bf6SEd Tanous                     const bool functional) {
1477da847b6SLakshmi Yadlapati         if (ec)
1487da847b6SLakshmi Yadlapati         {
1497da847b6SLakshmi Yadlapati             if (ec.value() != EBADR)
1507da847b6SLakshmi Yadlapati             {
15162598e31SEd Tanous                 BMCWEB_LOG_ERROR("DBUS response error for Health");
152ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
1537da847b6SLakshmi Yadlapati             }
1547da847b6SLakshmi Yadlapati             return;
1557da847b6SLakshmi Yadlapati         }
1567da847b6SLakshmi Yadlapati 
1577da847b6SLakshmi Yadlapati         if (!functional)
1587da847b6SLakshmi Yadlapati         {
159*539d8c6bSEd Tanous             asyncResp->res.jsonValue["Status"]["Health"] =
160*539d8c6bSEd Tanous                 resource::Health::Critical;
1617da847b6SLakshmi Yadlapati         }
1627da847b6SLakshmi Yadlapati     });
1637da847b6SLakshmi Yadlapati }
1647da847b6SLakshmi Yadlapati 
165ac106bf6SEd Tanous inline void doAdapterGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1663179105bSSunny Srivastava                          const std::string& systemName,
16753ffeca5SLakshmi Yadlapati                          const std::string& adapterId,
16853ffeca5SLakshmi Yadlapati                          const std::string& fabricAdapterPath,
16953ffeca5SLakshmi Yadlapati                          const std::string& serviceName)
1703179105bSSunny Srivastava {
171ac106bf6SEd Tanous     asyncResp->res.addHeader(
1723179105bSSunny Srivastava         boost::beast::http::field::link,
1733179105bSSunny Srivastava         "</redfish/v1/JsonSchemas/FabricAdapter/FabricAdapter.json>; rel=describedby");
174ac106bf6SEd Tanous     asyncResp->res.jsonValue["@odata.type"] =
175ac106bf6SEd Tanous         "#FabricAdapter.v1_4_0.FabricAdapter";
176ac106bf6SEd Tanous     asyncResp->res.jsonValue["Name"] = "Fabric Adapter";
177ac106bf6SEd Tanous     asyncResp->res.jsonValue["Id"] = adapterId;
178ac106bf6SEd Tanous     asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
179ef4c65b7SEd Tanous         "/redfish/v1/Systems/{}/FabricAdapters/{}", systemName, adapterId);
18053ffeca5SLakshmi Yadlapati 
181*539d8c6bSEd Tanous     asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
182*539d8c6bSEd Tanous     asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK;
183cd7af44fSLakshmi Yadlapati 
184ac106bf6SEd Tanous     getFabricAdapterLocation(asyncResp, serviceName, fabricAdapterPath);
185ac106bf6SEd Tanous     getFabricAdapterAsset(asyncResp, serviceName, fabricAdapterPath);
186ac106bf6SEd Tanous     getFabricAdapterState(asyncResp, serviceName, fabricAdapterPath);
187ac106bf6SEd Tanous     getFabricAdapterHealth(asyncResp, serviceName, fabricAdapterPath);
1883179105bSSunny Srivastava }
1893179105bSSunny Srivastava 
19078c90203SMyung Bae inline void afterGetValidFabricAdapterPath(
19178c90203SMyung Bae     const std::string& adapterId,
19278c90203SMyung Bae     std::function<void(const boost::system::error_code&,
19378c90203SMyung Bae                        const std::string& fabricAdapterPath,
19478c90203SMyung Bae                        const std::string& serviceName)>& callback,
19578c90203SMyung Bae     const boost::system::error_code& ec,
19678c90203SMyung Bae     const dbus::utility::MapperGetSubTreeResponse& subtree)
19778c90203SMyung Bae {
19878c90203SMyung Bae     std::string fabricAdapterPath;
19978c90203SMyung Bae     std::string serviceName;
20078c90203SMyung Bae     if (ec)
20178c90203SMyung Bae     {
20278c90203SMyung Bae         callback(ec, fabricAdapterPath, serviceName);
20378c90203SMyung Bae         return;
20478c90203SMyung Bae     }
20578c90203SMyung Bae 
20678c90203SMyung Bae     for (const auto& [adapterPath, serviceMap] : subtree)
2073179105bSSunny Srivastava     {
2083179105bSSunny Srivastava         std::string fabricAdapterName =
2093179105bSSunny Srivastava             sdbusplus::message::object_path(adapterPath).filename();
21078c90203SMyung Bae         if (fabricAdapterName == adapterId)
21178c90203SMyung Bae         {
21278c90203SMyung Bae             fabricAdapterPath = adapterPath;
21378c90203SMyung Bae             serviceName = serviceMap.begin()->first;
21478c90203SMyung Bae             break;
21578c90203SMyung Bae         }
21678c90203SMyung Bae     }
21778c90203SMyung Bae     callback(ec, fabricAdapterPath, serviceName);
2183179105bSSunny Srivastava }
2193179105bSSunny Srivastava 
2203179105bSSunny Srivastava inline void getValidFabricAdapterPath(
22178c90203SMyung Bae     const std::string& adapterId,
22278c90203SMyung Bae     std::function<void(const boost::system::error_code& ec,
22378c90203SMyung Bae                        const std::string& fabricAdapterPath,
2243179105bSSunny Srivastava                        const std::string& serviceName)>&& callback)
2253179105bSSunny Srivastava {
2263179105bSSunny Srivastava     constexpr std::array<std::string_view, 1> interfaces{
2273179105bSSunny Srivastava         "xyz.openbmc_project.Inventory.Item.FabricAdapter"};
22878c90203SMyung Bae     dbus::utility::getSubTree("/xyz/openbmc_project/inventory", 0, interfaces,
22978c90203SMyung Bae                               std::bind_front(afterGetValidFabricAdapterPath,
23078c90203SMyung Bae                                               adapterId, std::move(callback)));
23178c90203SMyung Bae }
2323179105bSSunny Srivastava 
23378c90203SMyung Bae inline void afterHandleFabricAdapterGet(
23478c90203SMyung Bae     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
23578c90203SMyung Bae     const std::string& systemName, const std::string& adapterId,
23678c90203SMyung Bae     const boost::system::error_code& ec, const std::string& fabricAdapterPath,
23778c90203SMyung Bae     const std::string& serviceName)
23878c90203SMyung Bae {
2393179105bSSunny Srivastava     if (ec)
2403179105bSSunny Srivastava     {
24178c90203SMyung Bae         if (ec.value() == boost::system::errc::io_error)
24278c90203SMyung Bae         {
24378c90203SMyung Bae             messages::resourceNotFound(asyncResp->res, "FabricAdapter",
24478c90203SMyung Bae                                        adapterId);
2453179105bSSunny Srivastava             return;
2463179105bSSunny Srivastava         }
24778c90203SMyung Bae 
24878c90203SMyung Bae         BMCWEB_LOG_ERROR("DBus method call failed with error {}", ec.value());
24978c90203SMyung Bae         messages::internalError(asyncResp->res);
2503179105bSSunny Srivastava         return;
2513179105bSSunny Srivastava     }
25278c90203SMyung Bae     if (fabricAdapterPath.empty() || serviceName.empty())
25378c90203SMyung Bae     {
25462598e31SEd Tanous         BMCWEB_LOG_WARNING("Adapter not found");
255ac106bf6SEd Tanous         messages::resourceNotFound(asyncResp->res, "FabricAdapter", adapterId);
25678c90203SMyung Bae         return;
25778c90203SMyung Bae     }
25878c90203SMyung Bae     doAdapterGet(asyncResp, systemName, adapterId, fabricAdapterPath,
25978c90203SMyung Bae                  serviceName);
2603179105bSSunny Srivastava }
2613179105bSSunny Srivastava 
2623179105bSSunny Srivastava inline void
2633179105bSSunny Srivastava     handleFabricAdapterGet(App& app, const crow::Request& req,
264ac106bf6SEd Tanous                            const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2653179105bSSunny Srivastava                            const std::string& systemName,
2663179105bSSunny Srivastava                            const std::string& adapterId)
2673179105bSSunny Srivastava {
268ac106bf6SEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2693179105bSSunny Srivastava     {
2703179105bSSunny Srivastava         return;
2713179105bSSunny Srivastava     }
27225b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
2737f3e84a1SEd Tanous     {
2747f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
2757f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2767f3e84a1SEd Tanous                                    systemName);
2777f3e84a1SEd Tanous         return;
2787f3e84a1SEd Tanous     }
279253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
28078c90203SMyung Bae     {
28178c90203SMyung Bae         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
28278c90203SMyung Bae                                    systemName);
28378c90203SMyung Bae         return;
28478c90203SMyung Bae     }
2853179105bSSunny Srivastava     getValidFabricAdapterPath(
28678c90203SMyung Bae         adapterId, std::bind_front(afterHandleFabricAdapterGet, asyncResp,
28778c90203SMyung Bae                                    systemName, adapterId));
2883179105bSSunny Srivastava }
2893179105bSSunny Srivastava 
2903179105bSSunny Srivastava inline void handleFabricAdapterCollectionGet(
2913179105bSSunny Srivastava     crow::App& app, const crow::Request& req,
292ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2933179105bSSunny Srivastava     const std::string& systemName)
2943179105bSSunny Srivastava {
295ac106bf6SEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2963179105bSSunny Srivastava     {
2973179105bSSunny Srivastava         return;
2983179105bSSunny Srivastava     }
29925b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
3007f3e84a1SEd Tanous     {
3017f3e84a1SEd Tanous         // Option currently returns no systems. TBD
3027f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3037f3e84a1SEd Tanous                                    systemName);
3047f3e84a1SEd Tanous         return;
3057f3e84a1SEd Tanous     }
306253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
3073179105bSSunny Srivastava     {
308ac106bf6SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
309ac106bf6SEd Tanous                                    systemName);
3103179105bSSunny Srivastava         return;
3113179105bSSunny Srivastava     }
3123179105bSSunny Srivastava 
313ac106bf6SEd Tanous     asyncResp->res.addHeader(
3143179105bSSunny Srivastava         boost::beast::http::field::link,
3153179105bSSunny Srivastava         "</redfish/v1/JsonSchemas/FabricAdapterCollection/FabricAdapterCollection.json>; rel=describedby");
316ac106bf6SEd Tanous     asyncResp->res.jsonValue["@odata.type"] =
3173179105bSSunny Srivastava         "#FabricAdapterCollection.FabricAdapterCollection";
318ac106bf6SEd Tanous     asyncResp->res.jsonValue["Name"] = "Fabric Adapter Collection";
319ac106bf6SEd Tanous     asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
320ef4c65b7SEd Tanous         "/redfish/v1/Systems/{}/FabricAdapters", systemName);
3213179105bSSunny Srivastava 
3223179105bSSunny Srivastava     constexpr std::array<std::string_view, 1> interfaces{
3233179105bSSunny Srivastava         "xyz.openbmc_project.Inventory.Item.FabricAdapter"};
3243179105bSSunny Srivastava     collection_util::getCollectionMembers(
325ac106bf6SEd Tanous         asyncResp,
326253f11b8SEd Tanous         boost::urls::format("/redfish/v1/Systems/{}/FabricAdapters",
327253f11b8SEd Tanous                             BMCWEB_REDFISH_SYSTEM_URI_NAME),
32836b5f1edSLakshmi Yadlapati         interfaces, "/xyz/openbmc_project/inventory");
3293179105bSSunny Srivastava }
3303179105bSSunny Srivastava 
3313179105bSSunny Srivastava inline void handleFabricAdapterCollectionHead(
3323179105bSSunny Srivastava     crow::App& app, const crow::Request& req,
333ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3343179105bSSunny Srivastava     const std::string& systemName)
3353179105bSSunny Srivastava {
336ac106bf6SEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3373179105bSSunny Srivastava     {
3383179105bSSunny Srivastava         return;
3393179105bSSunny Srivastava     }
34025b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
3417f3e84a1SEd Tanous     {
3427f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
3437f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3447f3e84a1SEd Tanous                                    systemName);
3457f3e84a1SEd Tanous         return;
3467f3e84a1SEd Tanous     }
347253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
3483179105bSSunny Srivastava     {
349ac106bf6SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
350ac106bf6SEd Tanous                                    systemName);
3513179105bSSunny Srivastava         return;
3523179105bSSunny Srivastava     }
353ac106bf6SEd Tanous     asyncResp->res.addHeader(
3543179105bSSunny Srivastava         boost::beast::http::field::link,
3553179105bSSunny Srivastava         "</redfish/v1/JsonSchemas/FabricAdapterCollection/FabricAdapterCollection.json>; rel=describedby");
3563179105bSSunny Srivastava }
3573179105bSSunny Srivastava 
35878c90203SMyung Bae inline void afterHandleFabricAdapterHead(
35978c90203SMyung Bae     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
36078c90203SMyung Bae     const std::string& adapterId, const boost::system::error_code& ec,
36178c90203SMyung Bae     const std::string& fabricAdapterPath, const std::string& serviceName)
36278c90203SMyung Bae {
36378c90203SMyung Bae     if (ec)
36478c90203SMyung Bae     {
36578c90203SMyung Bae         if (ec.value() == boost::system::errc::io_error)
36678c90203SMyung Bae         {
36778c90203SMyung Bae             messages::resourceNotFound(asyncResp->res, "FabricAdapter",
36878c90203SMyung Bae                                        adapterId);
36978c90203SMyung Bae             return;
37078c90203SMyung Bae         }
37178c90203SMyung Bae 
37278c90203SMyung Bae         BMCWEB_LOG_ERROR("DBus method call failed with error {}", ec.value());
37378c90203SMyung Bae         messages::internalError(asyncResp->res);
37478c90203SMyung Bae         return;
37578c90203SMyung Bae     }
37678c90203SMyung Bae     if (fabricAdapterPath.empty() || serviceName.empty())
37778c90203SMyung Bae     {
37878c90203SMyung Bae         BMCWEB_LOG_WARNING("Adapter not found");
37978c90203SMyung Bae         messages::resourceNotFound(asyncResp->res, "FabricAdapter", adapterId);
38078c90203SMyung Bae         return;
38178c90203SMyung Bae     }
38278c90203SMyung Bae     asyncResp->res.addHeader(
38378c90203SMyung Bae         boost::beast::http::field::link,
38478c90203SMyung Bae         "</redfish/v1/JsonSchemas/FabricAdapter/FabricAdapter.json>; rel=describedby");
38578c90203SMyung Bae }
38678c90203SMyung Bae 
3873179105bSSunny Srivastava inline void
3883179105bSSunny Srivastava     handleFabricAdapterHead(crow::App& app, const crow::Request& req,
389ac106bf6SEd Tanous                             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3903179105bSSunny Srivastava                             const std::string& systemName,
3913179105bSSunny Srivastava                             const std::string& adapterId)
3923179105bSSunny Srivastava {
393ac106bf6SEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3943179105bSSunny Srivastava     {
3953179105bSSunny Srivastava         return;
3963179105bSSunny Srivastava     }
3973179105bSSunny Srivastava 
39825b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
3997f3e84a1SEd Tanous     {
4007f3e84a1SEd Tanous         // Option currently returns no systems. TBD
4017f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
4027f3e84a1SEd Tanous                                    systemName);
4037f3e84a1SEd Tanous         return;
4047f3e84a1SEd Tanous     }
405253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
40678c90203SMyung Bae     {
40778c90203SMyung Bae         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
40878c90203SMyung Bae                                    systemName);
40978c90203SMyung Bae         return;
41078c90203SMyung Bae     }
41178c90203SMyung Bae     getValidFabricAdapterPath(
41278c90203SMyung Bae         adapterId,
41378c90203SMyung Bae         std::bind_front(afterHandleFabricAdapterHead, asyncResp, adapterId));
4143179105bSSunny Srivastava }
4153179105bSSunny Srivastava 
4163179105bSSunny Srivastava inline void requestRoutesFabricAdapterCollection(App& app)
4173179105bSSunny Srivastava {
4183179105bSSunny Srivastava     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/")
4193179105bSSunny Srivastava         .privileges(redfish::privileges::getFabricAdapterCollection)
4203179105bSSunny Srivastava         .methods(boost::beast::http::verb::get)(
4213179105bSSunny Srivastava             std::bind_front(handleFabricAdapterCollectionGet, std::ref(app)));
4223179105bSSunny Srivastava 
4233179105bSSunny Srivastava     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/")
4243179105bSSunny Srivastava         .privileges(redfish::privileges::headFabricAdapterCollection)
4253179105bSSunny Srivastava         .methods(boost::beast::http::verb::head)(
4263179105bSSunny Srivastava             std::bind_front(handleFabricAdapterCollectionHead, std::ref(app)));
4273179105bSSunny Srivastava }
4283179105bSSunny Srivastava 
4293179105bSSunny Srivastava inline void requestRoutesFabricAdapters(App& app)
4303179105bSSunny Srivastava {
4313179105bSSunny Srivastava     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/<str>/")
4323179105bSSunny Srivastava         .privileges(redfish::privileges::getFabricAdapter)
4333179105bSSunny Srivastava         .methods(boost::beast::http::verb::get)(
4343179105bSSunny Srivastava             std::bind_front(handleFabricAdapterGet, std::ref(app)));
4353179105bSSunny Srivastava 
4363179105bSSunny Srivastava     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/<str>/")
4373179105bSSunny Srivastava         .privileges(redfish::privileges::headFabricAdapter)
4383179105bSSunny Srivastava         .methods(boost::beast::http::verb::head)(
4393179105bSSunny Srivastava             std::bind_front(handleFabricAdapterHead, std::ref(app)));
4403179105bSSunny Srivastava }
4413179105bSSunny Srivastava } // namespace redfish
442