xref: /openbmc/bmcweb/features/redfish/lib/fabric_adapters.hpp (revision bd79bce8c3f1deb1fb2773868b9ece25233cf27b)
13179105bSSunny Srivastava #pragma once
23179105bSSunny Srivastava 
33179105bSSunny Srivastava #include "app.hpp"
43179105bSSunny Srivastava #include "dbus_utility.hpp"
5539d8c6bSEd 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 
46*bd79bce8SPatrick Williams             asyncResp->res
47*bd79bce8SPatrick Williams                 .jsonValue["Location"]["PartLocation"]["ServiceLabel"] =
4853ffeca5SLakshmi Yadlapati                 property;
4953ffeca5SLakshmi Yadlapati         });
5053ffeca5SLakshmi Yadlapati }
5153ffeca5SLakshmi Yadlapati 
52*bd79bce8SPatrick Williams inline void getFabricAdapterAsset(
53*bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
54*bd79bce8SPatrick Williams     const std::string& serviceName, 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(
78*bd79bce8SPatrick Williams                 dbus_utils::UnpackErrorPrinter(), propertiesList,
79*bd79bce8SPatrick Williams                 "SerialNumber", serialNumber, "Model", model, "PartNumber",
80*bd79bce8SPatrick Williams                 partNumber, "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 
110*bd79bce8SPatrick Williams inline void getFabricAdapterState(
111*bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
112*bd79bce8SPatrick Williams     const std::string& serviceName, const std::string& fabricAdapterPath)
113cd7af44fSLakshmi Yadlapati {
114cd7af44fSLakshmi Yadlapati     sdbusplus::asio::getProperty<bool>(
115cd7af44fSLakshmi Yadlapati         *crow::connections::systemBus, serviceName, fabricAdapterPath,
116cd7af44fSLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Item", "Present",
117ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec, const bool present) {
118cd7af44fSLakshmi Yadlapati             if (ec)
119cd7af44fSLakshmi Yadlapati             {
120cd7af44fSLakshmi Yadlapati                 if (ec.value() != EBADR)
121cd7af44fSLakshmi Yadlapati                 {
12262598e31SEd Tanous                     BMCWEB_LOG_ERROR("DBUS response error for State");
123ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
124cd7af44fSLakshmi Yadlapati                 }
125cd7af44fSLakshmi Yadlapati                 return;
126cd7af44fSLakshmi Yadlapati             }
127cd7af44fSLakshmi Yadlapati 
128cd7af44fSLakshmi Yadlapati             if (!present)
129cd7af44fSLakshmi Yadlapati             {
130539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
131539d8c6bSEd Tanous                     resource::State::Absent;
132cd7af44fSLakshmi Yadlapati             }
133cd7af44fSLakshmi Yadlapati         });
134cd7af44fSLakshmi Yadlapati }
135cd7af44fSLakshmi Yadlapati 
136*bd79bce8SPatrick Williams inline void getFabricAdapterHealth(
137*bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
138*bd79bce8SPatrick Williams     const std::string& serviceName, const std::string& fabricAdapterPath)
1397da847b6SLakshmi Yadlapati {
1407da847b6SLakshmi Yadlapati     sdbusplus::asio::getProperty<bool>(
1417da847b6SLakshmi Yadlapati         *crow::connections::systemBus, serviceName, fabricAdapterPath,
1427da847b6SLakshmi Yadlapati         "xyz.openbmc_project.State.Decorator.OperationalStatus", "Functional",
143ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
144ac106bf6SEd Tanous                     const bool functional) {
1457da847b6SLakshmi Yadlapati             if (ec)
1467da847b6SLakshmi Yadlapati             {
1477da847b6SLakshmi Yadlapati                 if (ec.value() != EBADR)
1487da847b6SLakshmi Yadlapati                 {
14962598e31SEd Tanous                     BMCWEB_LOG_ERROR("DBUS response error for Health");
150ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
1517da847b6SLakshmi Yadlapati                 }
1527da847b6SLakshmi Yadlapati                 return;
1537da847b6SLakshmi Yadlapati             }
1547da847b6SLakshmi Yadlapati 
1557da847b6SLakshmi Yadlapati             if (!functional)
1567da847b6SLakshmi Yadlapati             {
157539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["Health"] =
158539d8c6bSEd Tanous                     resource::Health::Critical;
1597da847b6SLakshmi Yadlapati             }
1607da847b6SLakshmi Yadlapati         });
1617da847b6SLakshmi Yadlapati }
1627da847b6SLakshmi Yadlapati 
163*bd79bce8SPatrick Williams inline void doAdapterGet(
164*bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
165*bd79bce8SPatrick Williams     const std::string& systemName, const std::string& adapterId,
166*bd79bce8SPatrick Williams     const std::string& fabricAdapterPath, const std::string& serviceName)
1673179105bSSunny Srivastava {
168ac106bf6SEd Tanous     asyncResp->res.addHeader(
1693179105bSSunny Srivastava         boost::beast::http::field::link,
1703179105bSSunny Srivastava         "</redfish/v1/JsonSchemas/FabricAdapter/FabricAdapter.json>; rel=describedby");
171ac106bf6SEd Tanous     asyncResp->res.jsonValue["@odata.type"] =
172ac106bf6SEd Tanous         "#FabricAdapter.v1_4_0.FabricAdapter";
173ac106bf6SEd Tanous     asyncResp->res.jsonValue["Name"] = "Fabric Adapter";
174ac106bf6SEd Tanous     asyncResp->res.jsonValue["Id"] = adapterId;
175ac106bf6SEd Tanous     asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
176ef4c65b7SEd Tanous         "/redfish/v1/Systems/{}/FabricAdapters/{}", systemName, adapterId);
17753ffeca5SLakshmi Yadlapati 
178539d8c6bSEd Tanous     asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
179539d8c6bSEd Tanous     asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK;
180cd7af44fSLakshmi Yadlapati 
181ac106bf6SEd Tanous     getFabricAdapterLocation(asyncResp, serviceName, fabricAdapterPath);
182ac106bf6SEd Tanous     getFabricAdapterAsset(asyncResp, serviceName, fabricAdapterPath);
183ac106bf6SEd Tanous     getFabricAdapterState(asyncResp, serviceName, fabricAdapterPath);
184ac106bf6SEd Tanous     getFabricAdapterHealth(asyncResp, serviceName, fabricAdapterPath);
1853179105bSSunny Srivastava }
1863179105bSSunny Srivastava 
18778c90203SMyung Bae inline void afterGetValidFabricAdapterPath(
18878c90203SMyung Bae     const std::string& adapterId,
18978c90203SMyung Bae     std::function<void(const boost::system::error_code&,
19078c90203SMyung Bae                        const std::string& fabricAdapterPath,
19178c90203SMyung Bae                        const std::string& serviceName)>& callback,
19278c90203SMyung Bae     const boost::system::error_code& ec,
19378c90203SMyung Bae     const dbus::utility::MapperGetSubTreeResponse& subtree)
19478c90203SMyung Bae {
19578c90203SMyung Bae     std::string fabricAdapterPath;
19678c90203SMyung Bae     std::string serviceName;
19778c90203SMyung Bae     if (ec)
19878c90203SMyung Bae     {
19978c90203SMyung Bae         callback(ec, fabricAdapterPath, serviceName);
20078c90203SMyung Bae         return;
20178c90203SMyung Bae     }
20278c90203SMyung Bae 
20378c90203SMyung Bae     for (const auto& [adapterPath, serviceMap] : subtree)
2043179105bSSunny Srivastava     {
2053179105bSSunny Srivastava         std::string fabricAdapterName =
2063179105bSSunny Srivastava             sdbusplus::message::object_path(adapterPath).filename();
20778c90203SMyung Bae         if (fabricAdapterName == adapterId)
20878c90203SMyung Bae         {
20978c90203SMyung Bae             fabricAdapterPath = adapterPath;
21078c90203SMyung Bae             serviceName = serviceMap.begin()->first;
21178c90203SMyung Bae             break;
21278c90203SMyung Bae         }
21378c90203SMyung Bae     }
21478c90203SMyung Bae     callback(ec, fabricAdapterPath, serviceName);
2153179105bSSunny Srivastava }
2163179105bSSunny Srivastava 
2173179105bSSunny Srivastava inline void getValidFabricAdapterPath(
21878c90203SMyung Bae     const std::string& adapterId,
21978c90203SMyung Bae     std::function<void(const boost::system::error_code& ec,
22078c90203SMyung Bae                        const std::string& fabricAdapterPath,
2213179105bSSunny Srivastava                        const std::string& serviceName)>&& callback)
2223179105bSSunny Srivastava {
2233179105bSSunny Srivastava     constexpr std::array<std::string_view, 1> interfaces{
2243179105bSSunny Srivastava         "xyz.openbmc_project.Inventory.Item.FabricAdapter"};
22578c90203SMyung Bae     dbus::utility::getSubTree("/xyz/openbmc_project/inventory", 0, interfaces,
22678c90203SMyung Bae                               std::bind_front(afterGetValidFabricAdapterPath,
22778c90203SMyung Bae                                               adapterId, std::move(callback)));
22878c90203SMyung Bae }
2293179105bSSunny Srivastava 
23078c90203SMyung Bae inline void afterHandleFabricAdapterGet(
23178c90203SMyung Bae     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
23278c90203SMyung Bae     const std::string& systemName, const std::string& adapterId,
23378c90203SMyung Bae     const boost::system::error_code& ec, const std::string& fabricAdapterPath,
23478c90203SMyung Bae     const std::string& serviceName)
23578c90203SMyung Bae {
2363179105bSSunny Srivastava     if (ec)
2373179105bSSunny Srivastava     {
23878c90203SMyung Bae         if (ec.value() == boost::system::errc::io_error)
23978c90203SMyung Bae         {
24078c90203SMyung Bae             messages::resourceNotFound(asyncResp->res, "FabricAdapter",
24178c90203SMyung Bae                                        adapterId);
2423179105bSSunny Srivastava             return;
2433179105bSSunny Srivastava         }
24478c90203SMyung Bae 
24578c90203SMyung Bae         BMCWEB_LOG_ERROR("DBus method call failed with error {}", ec.value());
24678c90203SMyung Bae         messages::internalError(asyncResp->res);
2473179105bSSunny Srivastava         return;
2483179105bSSunny Srivastava     }
24978c90203SMyung Bae     if (fabricAdapterPath.empty() || serviceName.empty())
25078c90203SMyung Bae     {
25162598e31SEd Tanous         BMCWEB_LOG_WARNING("Adapter not found");
252ac106bf6SEd Tanous         messages::resourceNotFound(asyncResp->res, "FabricAdapter", adapterId);
25378c90203SMyung Bae         return;
25478c90203SMyung Bae     }
25578c90203SMyung Bae     doAdapterGet(asyncResp, systemName, adapterId, fabricAdapterPath,
25678c90203SMyung Bae                  serviceName);
2573179105bSSunny Srivastava }
2583179105bSSunny Srivastava 
259*bd79bce8SPatrick Williams inline void handleFabricAdapterGet(
260*bd79bce8SPatrick Williams     App& app, const crow::Request& req,
261ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
262*bd79bce8SPatrick Williams     const std::string& systemName, const std::string& adapterId)
2633179105bSSunny Srivastava {
264ac106bf6SEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2653179105bSSunny Srivastava     {
2663179105bSSunny Srivastava         return;
2673179105bSSunny Srivastava     }
26825b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
2697f3e84a1SEd Tanous     {
2707f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
2717f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2727f3e84a1SEd Tanous                                    systemName);
2737f3e84a1SEd Tanous         return;
2747f3e84a1SEd Tanous     }
275253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
27678c90203SMyung Bae     {
27778c90203SMyung Bae         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
27878c90203SMyung Bae                                    systemName);
27978c90203SMyung Bae         return;
28078c90203SMyung Bae     }
2813179105bSSunny Srivastava     getValidFabricAdapterPath(
28278c90203SMyung Bae         adapterId, std::bind_front(afterHandleFabricAdapterGet, asyncResp,
28378c90203SMyung Bae                                    systemName, adapterId));
2843179105bSSunny Srivastava }
2853179105bSSunny Srivastava 
2863179105bSSunny Srivastava inline void handleFabricAdapterCollectionGet(
2873179105bSSunny Srivastava     crow::App& app, const crow::Request& req,
288ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2893179105bSSunny Srivastava     const std::string& systemName)
2903179105bSSunny Srivastava {
291ac106bf6SEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2923179105bSSunny Srivastava     {
2933179105bSSunny Srivastava         return;
2943179105bSSunny Srivastava     }
29525b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
2967f3e84a1SEd Tanous     {
2977f3e84a1SEd Tanous         // Option currently returns no systems. TBD
2987f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2997f3e84a1SEd Tanous                                    systemName);
3007f3e84a1SEd Tanous         return;
3017f3e84a1SEd Tanous     }
302253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
3033179105bSSunny Srivastava     {
304ac106bf6SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
305ac106bf6SEd Tanous                                    systemName);
3063179105bSSunny Srivastava         return;
3073179105bSSunny Srivastava     }
3083179105bSSunny Srivastava 
309ac106bf6SEd Tanous     asyncResp->res.addHeader(
3103179105bSSunny Srivastava         boost::beast::http::field::link,
3113179105bSSunny Srivastava         "</redfish/v1/JsonSchemas/FabricAdapterCollection/FabricAdapterCollection.json>; rel=describedby");
312ac106bf6SEd Tanous     asyncResp->res.jsonValue["@odata.type"] =
3133179105bSSunny Srivastava         "#FabricAdapterCollection.FabricAdapterCollection";
314ac106bf6SEd Tanous     asyncResp->res.jsonValue["Name"] = "Fabric Adapter Collection";
315ac106bf6SEd Tanous     asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
316ef4c65b7SEd Tanous         "/redfish/v1/Systems/{}/FabricAdapters", systemName);
3173179105bSSunny Srivastava 
3183179105bSSunny Srivastava     constexpr std::array<std::string_view, 1> interfaces{
3193179105bSSunny Srivastava         "xyz.openbmc_project.Inventory.Item.FabricAdapter"};
3203179105bSSunny Srivastava     collection_util::getCollectionMembers(
321ac106bf6SEd Tanous         asyncResp,
322253f11b8SEd Tanous         boost::urls::format("/redfish/v1/Systems/{}/FabricAdapters",
323253f11b8SEd Tanous                             BMCWEB_REDFISH_SYSTEM_URI_NAME),
32436b5f1edSLakshmi Yadlapati         interfaces, "/xyz/openbmc_project/inventory");
3253179105bSSunny Srivastava }
3263179105bSSunny Srivastava 
3273179105bSSunny Srivastava inline void handleFabricAdapterCollectionHead(
3283179105bSSunny Srivastava     crow::App& app, const crow::Request& req,
329ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3303179105bSSunny Srivastava     const std::string& systemName)
3313179105bSSunny Srivastava {
332ac106bf6SEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3333179105bSSunny Srivastava     {
3343179105bSSunny Srivastava         return;
3353179105bSSunny Srivastava     }
33625b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
3377f3e84a1SEd Tanous     {
3387f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
3397f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3407f3e84a1SEd Tanous                                    systemName);
3417f3e84a1SEd Tanous         return;
3427f3e84a1SEd Tanous     }
343253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
3443179105bSSunny Srivastava     {
345ac106bf6SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
346ac106bf6SEd Tanous                                    systemName);
3473179105bSSunny Srivastava         return;
3483179105bSSunny Srivastava     }
349ac106bf6SEd Tanous     asyncResp->res.addHeader(
3503179105bSSunny Srivastava         boost::beast::http::field::link,
3513179105bSSunny Srivastava         "</redfish/v1/JsonSchemas/FabricAdapterCollection/FabricAdapterCollection.json>; rel=describedby");
3523179105bSSunny Srivastava }
3533179105bSSunny Srivastava 
35478c90203SMyung Bae inline void afterHandleFabricAdapterHead(
35578c90203SMyung Bae     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
35678c90203SMyung Bae     const std::string& adapterId, const boost::system::error_code& ec,
35778c90203SMyung Bae     const std::string& fabricAdapterPath, const std::string& serviceName)
35878c90203SMyung Bae {
35978c90203SMyung Bae     if (ec)
36078c90203SMyung Bae     {
36178c90203SMyung Bae         if (ec.value() == boost::system::errc::io_error)
36278c90203SMyung Bae         {
36378c90203SMyung Bae             messages::resourceNotFound(asyncResp->res, "FabricAdapter",
36478c90203SMyung Bae                                        adapterId);
36578c90203SMyung Bae             return;
36678c90203SMyung Bae         }
36778c90203SMyung Bae 
36878c90203SMyung Bae         BMCWEB_LOG_ERROR("DBus method call failed with error {}", ec.value());
36978c90203SMyung Bae         messages::internalError(asyncResp->res);
37078c90203SMyung Bae         return;
37178c90203SMyung Bae     }
37278c90203SMyung Bae     if (fabricAdapterPath.empty() || serviceName.empty())
37378c90203SMyung Bae     {
37478c90203SMyung Bae         BMCWEB_LOG_WARNING("Adapter not found");
37578c90203SMyung Bae         messages::resourceNotFound(asyncResp->res, "FabricAdapter", adapterId);
37678c90203SMyung Bae         return;
37778c90203SMyung Bae     }
37878c90203SMyung Bae     asyncResp->res.addHeader(
37978c90203SMyung Bae         boost::beast::http::field::link,
38078c90203SMyung Bae         "</redfish/v1/JsonSchemas/FabricAdapter/FabricAdapter.json>; rel=describedby");
38178c90203SMyung Bae }
38278c90203SMyung Bae 
383*bd79bce8SPatrick Williams inline void handleFabricAdapterHead(
384*bd79bce8SPatrick Williams     crow::App& app, const crow::Request& req,
385ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
386*bd79bce8SPatrick Williams     const std::string& systemName, const std::string& adapterId)
3873179105bSSunny Srivastava {
388ac106bf6SEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3893179105bSSunny Srivastava     {
3903179105bSSunny Srivastava         return;
3913179105bSSunny Srivastava     }
3923179105bSSunny Srivastava 
39325b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
3947f3e84a1SEd Tanous     {
3957f3e84a1SEd Tanous         // Option currently returns no systems. TBD
3967f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3977f3e84a1SEd Tanous                                    systemName);
3987f3e84a1SEd Tanous         return;
3997f3e84a1SEd Tanous     }
400253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
40178c90203SMyung Bae     {
40278c90203SMyung Bae         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
40378c90203SMyung Bae                                    systemName);
40478c90203SMyung Bae         return;
40578c90203SMyung Bae     }
40678c90203SMyung Bae     getValidFabricAdapterPath(
40778c90203SMyung Bae         adapterId,
40878c90203SMyung Bae         std::bind_front(afterHandleFabricAdapterHead, asyncResp, adapterId));
4093179105bSSunny Srivastava }
4103179105bSSunny Srivastava 
4113179105bSSunny Srivastava inline void requestRoutesFabricAdapterCollection(App& app)
4123179105bSSunny Srivastava {
4133179105bSSunny Srivastava     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/")
4143179105bSSunny Srivastava         .privileges(redfish::privileges::getFabricAdapterCollection)
4153179105bSSunny Srivastava         .methods(boost::beast::http::verb::get)(
4163179105bSSunny Srivastava             std::bind_front(handleFabricAdapterCollectionGet, std::ref(app)));
4173179105bSSunny Srivastava 
4183179105bSSunny Srivastava     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/")
4193179105bSSunny Srivastava         .privileges(redfish::privileges::headFabricAdapterCollection)
4203179105bSSunny Srivastava         .methods(boost::beast::http::verb::head)(
4213179105bSSunny Srivastava             std::bind_front(handleFabricAdapterCollectionHead, std::ref(app)));
4223179105bSSunny Srivastava }
4233179105bSSunny Srivastava 
4243179105bSSunny Srivastava inline void requestRoutesFabricAdapters(App& app)
4253179105bSSunny Srivastava {
4263179105bSSunny Srivastava     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/<str>/")
4273179105bSSunny Srivastava         .privileges(redfish::privileges::getFabricAdapter)
4283179105bSSunny Srivastava         .methods(boost::beast::http::verb::get)(
4293179105bSSunny Srivastava             std::bind_front(handleFabricAdapterGet, std::ref(app)));
4303179105bSSunny Srivastava 
4313179105bSSunny Srivastava     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/<str>/")
4323179105bSSunny Srivastava         .privileges(redfish::privileges::headFabricAdapter)
4333179105bSSunny Srivastava         .methods(boost::beast::http::verb::head)(
4343179105bSSunny Srivastava             std::bind_front(handleFabricAdapterHead, std::ref(app)));
4353179105bSSunny Srivastava }
4363179105bSSunny Srivastava } // namespace redfish
437