xref: /openbmc/bmcweb/features/redfish/lib/fabric_adapters.hpp (revision f7e62c142ced153e9400b519bdd66062dd6bbf0e)
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"
17*f7e62c14SMyung Bae #include "utils/asset_utils.hpp"
183179105bSSunny Srivastava #include "utils/collection.hpp"
196177a301SLakshmi Yadlapati #include "utils/dbus_utils.hpp"
20be1384e3SMyung Bae #include "utils/json_utils.hpp"
213179105bSSunny Srivastava 
22d7857201SEd Tanous #include <asm-generic/errno.h>
23d7857201SEd Tanous 
24d7857201SEd Tanous #include <boost/beast/http/field.hpp>
25d7857201SEd Tanous #include <boost/beast/http/verb.hpp>
263179105bSSunny Srivastava #include <boost/system/error_code.hpp>
27ef4c65b7SEd Tanous #include <boost/url/format.hpp>
286177a301SLakshmi Yadlapati #include <sdbusplus/unpack_properties.hpp>
293179105bSSunny Srivastava 
303179105bSSunny Srivastava #include <array>
313179105bSSunny Srivastava #include <functional>
323179105bSSunny Srivastava #include <memory>
33be1384e3SMyung Bae #include <optional>
343179105bSSunny Srivastava #include <string>
353179105bSSunny Srivastava #include <string_view>
36d7857201SEd Tanous #include <utility>
373179105bSSunny Srivastava 
383179105bSSunny Srivastava namespace redfish
393179105bSSunny Srivastava {
403179105bSSunny Srivastava 
41ac106bf6SEd Tanous inline void getFabricAdapterLocation(
42ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
43ac106bf6SEd Tanous     const std::string& serviceName, const std::string& fabricAdapterPath)
4453ffeca5SLakshmi Yadlapati {
45deae6a78SEd Tanous     dbus::utility::getProperty<std::string>(
46deae6a78SEd Tanous         serviceName, fabricAdapterPath,
4753ffeca5SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Decorator.LocationCode", "LocationCode",
48ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
4953ffeca5SLakshmi Yadlapati                     const std::string& property) {
5053ffeca5SLakshmi Yadlapati             if (ec)
5153ffeca5SLakshmi Yadlapati             {
5253ffeca5SLakshmi Yadlapati                 if (ec.value() != EBADR)
5353ffeca5SLakshmi Yadlapati                 {
5462598e31SEd Tanous                     BMCWEB_LOG_ERROR("DBUS response error for Location");
55ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
5653ffeca5SLakshmi Yadlapati                 }
5753ffeca5SLakshmi Yadlapati                 return;
5853ffeca5SLakshmi Yadlapati             }
5953ffeca5SLakshmi Yadlapati 
60bd79bce8SPatrick Williams             asyncResp->res
61bd79bce8SPatrick Williams                 .jsonValue["Location"]["PartLocation"]["ServiceLabel"] =
6253ffeca5SLakshmi Yadlapati                 property;
6353ffeca5SLakshmi Yadlapati         });
6453ffeca5SLakshmi Yadlapati }
6553ffeca5SLakshmi Yadlapati 
66bd79bce8SPatrick Williams inline void getFabricAdapterState(
67bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
68bd79bce8SPatrick Williams     const std::string& serviceName, const std::string& fabricAdapterPath)
69cd7af44fSLakshmi Yadlapati {
70deae6a78SEd Tanous     dbus::utility::getProperty<bool>(
71deae6a78SEd Tanous         serviceName, fabricAdapterPath, "xyz.openbmc_project.Inventory.Item",
72deae6a78SEd Tanous         "Present",
73ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec, const bool present) {
74cd7af44fSLakshmi Yadlapati             if (ec)
75cd7af44fSLakshmi Yadlapati             {
76cd7af44fSLakshmi Yadlapati                 if (ec.value() != EBADR)
77cd7af44fSLakshmi Yadlapati                 {
7862598e31SEd Tanous                     BMCWEB_LOG_ERROR("DBUS response error for State");
79ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
80cd7af44fSLakshmi Yadlapati                 }
81cd7af44fSLakshmi Yadlapati                 return;
82cd7af44fSLakshmi Yadlapati             }
83cd7af44fSLakshmi Yadlapati 
84cd7af44fSLakshmi Yadlapati             if (!present)
85cd7af44fSLakshmi Yadlapati             {
86539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
87539d8c6bSEd Tanous                     resource::State::Absent;
88cd7af44fSLakshmi Yadlapati             }
89cd7af44fSLakshmi Yadlapati         });
90cd7af44fSLakshmi Yadlapati }
91cd7af44fSLakshmi Yadlapati 
92bd79bce8SPatrick Williams inline void getFabricAdapterHealth(
93bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
94bd79bce8SPatrick Williams     const std::string& serviceName, const std::string& fabricAdapterPath)
957da847b6SLakshmi Yadlapati {
96deae6a78SEd Tanous     dbus::utility::getProperty<bool>(
97deae6a78SEd Tanous         serviceName, fabricAdapterPath,
987da847b6SLakshmi Yadlapati         "xyz.openbmc_project.State.Decorator.OperationalStatus", "Functional",
99ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
100ac106bf6SEd Tanous                     const bool functional) {
1017da847b6SLakshmi Yadlapati             if (ec)
1027da847b6SLakshmi Yadlapati             {
1037da847b6SLakshmi Yadlapati                 if (ec.value() != EBADR)
1047da847b6SLakshmi Yadlapati                 {
10562598e31SEd Tanous                     BMCWEB_LOG_ERROR("DBUS response error for Health");
106ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
1077da847b6SLakshmi Yadlapati                 }
1087da847b6SLakshmi Yadlapati                 return;
1097da847b6SLakshmi Yadlapati             }
1107da847b6SLakshmi Yadlapati 
1117da847b6SLakshmi Yadlapati             if (!functional)
1127da847b6SLakshmi Yadlapati             {
113539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["Health"] =
114539d8c6bSEd Tanous                     resource::Health::Critical;
1157da847b6SLakshmi Yadlapati             }
1167da847b6SLakshmi Yadlapati         });
1177da847b6SLakshmi Yadlapati }
1187da847b6SLakshmi Yadlapati 
119bd79bce8SPatrick Williams inline void doAdapterGet(
120bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
121bd79bce8SPatrick Williams     const std::string& systemName, const std::string& adapterId,
122bd79bce8SPatrick Williams     const std::string& fabricAdapterPath, const std::string& serviceName)
1233179105bSSunny Srivastava {
124ac106bf6SEd Tanous     asyncResp->res.addHeader(
1253179105bSSunny Srivastava         boost::beast::http::field::link,
1263179105bSSunny Srivastava         "</redfish/v1/JsonSchemas/FabricAdapter/FabricAdapter.json>; rel=describedby");
127ac106bf6SEd Tanous     asyncResp->res.jsonValue["@odata.type"] =
128ac106bf6SEd Tanous         "#FabricAdapter.v1_4_0.FabricAdapter";
129ac106bf6SEd Tanous     asyncResp->res.jsonValue["Name"] = "Fabric Adapter";
130ac106bf6SEd Tanous     asyncResp->res.jsonValue["Id"] = adapterId;
131ac106bf6SEd Tanous     asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
132ef4c65b7SEd Tanous         "/redfish/v1/Systems/{}/FabricAdapters/{}", systemName, adapterId);
13353ffeca5SLakshmi Yadlapati 
134539d8c6bSEd Tanous     asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
135539d8c6bSEd Tanous     asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK;
136cd7af44fSLakshmi Yadlapati 
13737937d51SGeorge Liu     asyncResp->res.jsonValue["Ports"]["@odata.id"] =
13837937d51SGeorge Liu         boost::urls::format("/redfish/v1/Systems/{}/FabricAdapters/{}/Ports",
13937937d51SGeorge Liu                             systemName, adapterId);
14037937d51SGeorge Liu 
141ac106bf6SEd Tanous     getFabricAdapterLocation(asyncResp, serviceName, fabricAdapterPath);
142*f7e62c14SMyung Bae     asset_utils::getAssetInfo(asyncResp, serviceName, fabricAdapterPath,
143*f7e62c14SMyung Bae                               ""_json_pointer, true);
144ac106bf6SEd Tanous     getFabricAdapterState(asyncResp, serviceName, fabricAdapterPath);
145ac106bf6SEd Tanous     getFabricAdapterHealth(asyncResp, serviceName, fabricAdapterPath);
146be1384e3SMyung Bae     getLocationIndicatorActive(asyncResp, fabricAdapterPath);
1473179105bSSunny Srivastava }
1483179105bSSunny Srivastava 
14978c90203SMyung Bae inline void afterGetValidFabricAdapterPath(
15078c90203SMyung Bae     const std::string& adapterId,
15178c90203SMyung Bae     std::function<void(const boost::system::error_code&,
15278c90203SMyung Bae                        const std::string& fabricAdapterPath,
15378c90203SMyung Bae                        const std::string& serviceName)>& callback,
15478c90203SMyung Bae     const boost::system::error_code& ec,
15578c90203SMyung Bae     const dbus::utility::MapperGetSubTreeResponse& subtree)
15678c90203SMyung Bae {
15778c90203SMyung Bae     std::string fabricAdapterPath;
15878c90203SMyung Bae     std::string serviceName;
15978c90203SMyung Bae     if (ec)
16078c90203SMyung Bae     {
16178c90203SMyung Bae         callback(ec, fabricAdapterPath, serviceName);
16278c90203SMyung Bae         return;
16378c90203SMyung Bae     }
16478c90203SMyung Bae 
16578c90203SMyung Bae     for (const auto& [adapterPath, serviceMap] : subtree)
1663179105bSSunny Srivastava     {
1673179105bSSunny Srivastava         std::string fabricAdapterName =
1683179105bSSunny Srivastava             sdbusplus::message::object_path(adapterPath).filename();
16978c90203SMyung Bae         if (fabricAdapterName == adapterId)
17078c90203SMyung Bae         {
17178c90203SMyung Bae             fabricAdapterPath = adapterPath;
17278c90203SMyung Bae             serviceName = serviceMap.begin()->first;
17378c90203SMyung Bae             break;
17478c90203SMyung Bae         }
17578c90203SMyung Bae     }
17678c90203SMyung Bae     callback(ec, fabricAdapterPath, serviceName);
1773179105bSSunny Srivastava }
1783179105bSSunny Srivastava 
1793179105bSSunny Srivastava inline void getValidFabricAdapterPath(
18078c90203SMyung Bae     const std::string& adapterId,
18178c90203SMyung Bae     std::function<void(const boost::system::error_code& ec,
18278c90203SMyung Bae                        const std::string& fabricAdapterPath,
1833179105bSSunny Srivastava                        const std::string& serviceName)>&& callback)
1843179105bSSunny Srivastava {
1853179105bSSunny Srivastava     constexpr std::array<std::string_view, 1> interfaces{
1863179105bSSunny Srivastava         "xyz.openbmc_project.Inventory.Item.FabricAdapter"};
18778c90203SMyung Bae     dbus::utility::getSubTree("/xyz/openbmc_project/inventory", 0, interfaces,
18878c90203SMyung Bae                               std::bind_front(afterGetValidFabricAdapterPath,
18978c90203SMyung Bae                                               adapterId, std::move(callback)));
19078c90203SMyung Bae }
1913179105bSSunny Srivastava 
19278c90203SMyung Bae inline void afterHandleFabricAdapterGet(
19378c90203SMyung Bae     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
19478c90203SMyung Bae     const std::string& systemName, const std::string& adapterId,
19578c90203SMyung Bae     const boost::system::error_code& ec, const std::string& fabricAdapterPath,
19678c90203SMyung Bae     const std::string& serviceName)
19778c90203SMyung Bae {
1983179105bSSunny Srivastava     if (ec)
1993179105bSSunny Srivastava     {
20078c90203SMyung Bae         if (ec.value() == boost::system::errc::io_error)
20178c90203SMyung Bae         {
20278c90203SMyung Bae             messages::resourceNotFound(asyncResp->res, "FabricAdapter",
20378c90203SMyung Bae                                        adapterId);
2043179105bSSunny Srivastava             return;
2053179105bSSunny Srivastava         }
20678c90203SMyung Bae 
20778c90203SMyung Bae         BMCWEB_LOG_ERROR("DBus method call failed with error {}", ec.value());
20878c90203SMyung Bae         messages::internalError(asyncResp->res);
2093179105bSSunny Srivastava         return;
2103179105bSSunny Srivastava     }
21178c90203SMyung Bae     if (fabricAdapterPath.empty() || serviceName.empty())
21278c90203SMyung Bae     {
21362598e31SEd Tanous         BMCWEB_LOG_WARNING("Adapter not found");
214ac106bf6SEd Tanous         messages::resourceNotFound(asyncResp->res, "FabricAdapter", adapterId);
21578c90203SMyung Bae         return;
21678c90203SMyung Bae     }
21778c90203SMyung Bae     doAdapterGet(asyncResp, systemName, adapterId, fabricAdapterPath,
21878c90203SMyung Bae                  serviceName);
2193179105bSSunny Srivastava }
2203179105bSSunny Srivastava 
221bd79bce8SPatrick Williams inline void handleFabricAdapterGet(
222bd79bce8SPatrick Williams     App& app, const crow::Request& req,
223ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
224bd79bce8SPatrick Williams     const std::string& systemName, const std::string& adapterId)
2253179105bSSunny Srivastava {
226ac106bf6SEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2273179105bSSunny Srivastava     {
2283179105bSSunny Srivastava         return;
2293179105bSSunny Srivastava     }
23025b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
2317f3e84a1SEd Tanous     {
2327f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
2337f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2347f3e84a1SEd Tanous                                    systemName);
2357f3e84a1SEd Tanous         return;
2367f3e84a1SEd Tanous     }
237253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
23878c90203SMyung Bae     {
23978c90203SMyung Bae         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
24078c90203SMyung Bae                                    systemName);
24178c90203SMyung Bae         return;
24278c90203SMyung Bae     }
2433179105bSSunny Srivastava     getValidFabricAdapterPath(
24478c90203SMyung Bae         adapterId, std::bind_front(afterHandleFabricAdapterGet, asyncResp,
24578c90203SMyung Bae                                    systemName, adapterId));
2463179105bSSunny Srivastava }
2473179105bSSunny Srivastava 
248be1384e3SMyung Bae inline void afterHandleFabricAdapterPatch(
249be1384e3SMyung Bae     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
250be1384e3SMyung Bae     const std::string& adapterId, std::optional<bool> locationIndicatorActive,
251be1384e3SMyung Bae     const boost::system::error_code& ec, const std::string& fabricAdapterPath,
252be1384e3SMyung Bae     const std::string& serviceName)
253be1384e3SMyung Bae {
254be1384e3SMyung Bae     if (ec)
255be1384e3SMyung Bae     {
256be1384e3SMyung Bae         if (ec.value() == boost::system::errc::io_error)
257be1384e3SMyung Bae         {
258be1384e3SMyung Bae             messages::resourceNotFound(asyncResp->res, "FabricAdapter",
259be1384e3SMyung Bae                                        adapterId);
260be1384e3SMyung Bae             return;
261be1384e3SMyung Bae         }
262be1384e3SMyung Bae 
263be1384e3SMyung Bae         BMCWEB_LOG_ERROR("DBus method call failed with error {}", ec.value());
264be1384e3SMyung Bae         messages::internalError(asyncResp->res);
265be1384e3SMyung Bae         return;
266be1384e3SMyung Bae     }
267be1384e3SMyung Bae     if (fabricAdapterPath.empty() || serviceName.empty())
268be1384e3SMyung Bae     {
269be1384e3SMyung Bae         BMCWEB_LOG_WARNING("Adapter {} not found", adapterId);
270be1384e3SMyung Bae         messages::resourceNotFound(asyncResp->res, "FabricAdapter", adapterId);
271be1384e3SMyung Bae         return;
272be1384e3SMyung Bae     }
273be1384e3SMyung Bae 
274be1384e3SMyung Bae     if (locationIndicatorActive)
275be1384e3SMyung Bae     {
276be1384e3SMyung Bae         setLocationIndicatorActive(asyncResp, fabricAdapterPath,
277be1384e3SMyung Bae                                    *locationIndicatorActive);
278be1384e3SMyung Bae     }
279be1384e3SMyung Bae }
280be1384e3SMyung Bae 
281be1384e3SMyung Bae inline void handleFabricAdapterPatch(
282be1384e3SMyung Bae     App& app, const crow::Request& req,
283be1384e3SMyung Bae     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
284be1384e3SMyung Bae     const std::string& systemName, const std::string& adapterId)
285be1384e3SMyung Bae {
286be1384e3SMyung Bae     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
287be1384e3SMyung Bae     {
288be1384e3SMyung Bae         return;
289be1384e3SMyung Bae     }
290be1384e3SMyung Bae     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
291be1384e3SMyung Bae     {
292be1384e3SMyung Bae         // Option currently returns no systems.  TBD
293be1384e3SMyung Bae         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
294be1384e3SMyung Bae                                    systemName);
295be1384e3SMyung Bae         return;
296be1384e3SMyung Bae     }
297be1384e3SMyung Bae     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
298be1384e3SMyung Bae     {
299be1384e3SMyung Bae         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
300be1384e3SMyung Bae                                    systemName);
301be1384e3SMyung Bae         return;
302be1384e3SMyung Bae     }
303be1384e3SMyung Bae 
304be1384e3SMyung Bae     std::optional<bool> locationIndicatorActive;
305be1384e3SMyung Bae 
306be1384e3SMyung Bae     if (!json_util::readJsonPatch(req, asyncResp->res,
307be1384e3SMyung Bae                                   "LocationIndicatorActive",
308be1384e3SMyung Bae                                   locationIndicatorActive))
309be1384e3SMyung Bae     {
310be1384e3SMyung Bae         return;
311be1384e3SMyung Bae     }
312be1384e3SMyung Bae 
313be1384e3SMyung Bae     getValidFabricAdapterPath(
314be1384e3SMyung Bae         adapterId, std::bind_front(afterHandleFabricAdapterPatch, asyncResp,
315be1384e3SMyung Bae                                    adapterId, locationIndicatorActive));
316be1384e3SMyung Bae }
317be1384e3SMyung Bae 
3183179105bSSunny Srivastava inline void handleFabricAdapterCollectionGet(
3193179105bSSunny Srivastava     crow::App& app, const crow::Request& req,
320ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3213179105bSSunny Srivastava     const std::string& systemName)
3223179105bSSunny Srivastava {
323ac106bf6SEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3243179105bSSunny Srivastava     {
3253179105bSSunny Srivastava         return;
3263179105bSSunny Srivastava     }
32725b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
3287f3e84a1SEd Tanous     {
3297f3e84a1SEd Tanous         // Option currently returns no systems. TBD
3307f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3317f3e84a1SEd Tanous                                    systemName);
3327f3e84a1SEd Tanous         return;
3337f3e84a1SEd Tanous     }
334253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
3353179105bSSunny Srivastava     {
336ac106bf6SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
337ac106bf6SEd Tanous                                    systemName);
3383179105bSSunny Srivastava         return;
3393179105bSSunny Srivastava     }
3403179105bSSunny Srivastava 
341ac106bf6SEd Tanous     asyncResp->res.addHeader(
3423179105bSSunny Srivastava         boost::beast::http::field::link,
3433179105bSSunny Srivastava         "</redfish/v1/JsonSchemas/FabricAdapterCollection/FabricAdapterCollection.json>; rel=describedby");
344ac106bf6SEd Tanous     asyncResp->res.jsonValue["@odata.type"] =
3453179105bSSunny Srivastava         "#FabricAdapterCollection.FabricAdapterCollection";
346ac106bf6SEd Tanous     asyncResp->res.jsonValue["Name"] = "Fabric Adapter Collection";
347ac106bf6SEd Tanous     asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
348ef4c65b7SEd Tanous         "/redfish/v1/Systems/{}/FabricAdapters", systemName);
3493179105bSSunny Srivastava 
3503179105bSSunny Srivastava     constexpr std::array<std::string_view, 1> interfaces{
3513179105bSSunny Srivastava         "xyz.openbmc_project.Inventory.Item.FabricAdapter"};
3523179105bSSunny Srivastava     collection_util::getCollectionMembers(
353ac106bf6SEd Tanous         asyncResp,
354253f11b8SEd Tanous         boost::urls::format("/redfish/v1/Systems/{}/FabricAdapters",
355253f11b8SEd Tanous                             BMCWEB_REDFISH_SYSTEM_URI_NAME),
35636b5f1edSLakshmi Yadlapati         interfaces, "/xyz/openbmc_project/inventory");
3573179105bSSunny Srivastava }
3583179105bSSunny Srivastava 
3593179105bSSunny Srivastava inline void handleFabricAdapterCollectionHead(
3603179105bSSunny Srivastava     crow::App& app, const crow::Request& req,
361ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3623179105bSSunny Srivastava     const std::string& systemName)
3633179105bSSunny Srivastava {
364ac106bf6SEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3653179105bSSunny Srivastava     {
3663179105bSSunny Srivastava         return;
3673179105bSSunny Srivastava     }
36825b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
3697f3e84a1SEd Tanous     {
3707f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
3717f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3727f3e84a1SEd Tanous                                    systemName);
3737f3e84a1SEd Tanous         return;
3747f3e84a1SEd Tanous     }
375253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
3763179105bSSunny Srivastava     {
377ac106bf6SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
378ac106bf6SEd Tanous                                    systemName);
3793179105bSSunny Srivastava         return;
3803179105bSSunny Srivastava     }
381ac106bf6SEd Tanous     asyncResp->res.addHeader(
3823179105bSSunny Srivastava         boost::beast::http::field::link,
3833179105bSSunny Srivastava         "</redfish/v1/JsonSchemas/FabricAdapterCollection/FabricAdapterCollection.json>; rel=describedby");
3843179105bSSunny Srivastava }
3853179105bSSunny Srivastava 
38678c90203SMyung Bae inline void afterHandleFabricAdapterHead(
38778c90203SMyung Bae     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
38878c90203SMyung Bae     const std::string& adapterId, const boost::system::error_code& ec,
38978c90203SMyung Bae     const std::string& fabricAdapterPath, const std::string& serviceName)
39078c90203SMyung Bae {
39178c90203SMyung Bae     if (ec)
39278c90203SMyung Bae     {
39378c90203SMyung Bae         if (ec.value() == boost::system::errc::io_error)
39478c90203SMyung Bae         {
39578c90203SMyung Bae             messages::resourceNotFound(asyncResp->res, "FabricAdapter",
39678c90203SMyung Bae                                        adapterId);
39778c90203SMyung Bae             return;
39878c90203SMyung Bae         }
39978c90203SMyung Bae 
40078c90203SMyung Bae         BMCWEB_LOG_ERROR("DBus method call failed with error {}", ec.value());
40178c90203SMyung Bae         messages::internalError(asyncResp->res);
40278c90203SMyung Bae         return;
40378c90203SMyung Bae     }
40478c90203SMyung Bae     if (fabricAdapterPath.empty() || serviceName.empty())
40578c90203SMyung Bae     {
40678c90203SMyung Bae         BMCWEB_LOG_WARNING("Adapter not found");
40778c90203SMyung Bae         messages::resourceNotFound(asyncResp->res, "FabricAdapter", adapterId);
40878c90203SMyung Bae         return;
40978c90203SMyung Bae     }
41078c90203SMyung Bae     asyncResp->res.addHeader(
41178c90203SMyung Bae         boost::beast::http::field::link,
41278c90203SMyung Bae         "</redfish/v1/JsonSchemas/FabricAdapter/FabricAdapter.json>; rel=describedby");
41378c90203SMyung Bae }
41478c90203SMyung Bae 
415bd79bce8SPatrick Williams inline void handleFabricAdapterHead(
416bd79bce8SPatrick Williams     crow::App& app, const crow::Request& req,
417ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
418bd79bce8SPatrick Williams     const std::string& systemName, const std::string& adapterId)
4193179105bSSunny Srivastava {
420ac106bf6SEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
4213179105bSSunny Srivastava     {
4223179105bSSunny Srivastava         return;
4233179105bSSunny Srivastava     }
4243179105bSSunny Srivastava 
42525b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
4267f3e84a1SEd Tanous     {
4277f3e84a1SEd Tanous         // Option currently returns no systems. TBD
4287f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
4297f3e84a1SEd Tanous                                    systemName);
4307f3e84a1SEd Tanous         return;
4317f3e84a1SEd Tanous     }
432253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
43378c90203SMyung Bae     {
43478c90203SMyung Bae         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
43578c90203SMyung Bae                                    systemName);
43678c90203SMyung Bae         return;
43778c90203SMyung Bae     }
43878c90203SMyung Bae     getValidFabricAdapterPath(
43978c90203SMyung Bae         adapterId,
44078c90203SMyung Bae         std::bind_front(afterHandleFabricAdapterHead, asyncResp, adapterId));
4413179105bSSunny Srivastava }
4423179105bSSunny Srivastava 
4433179105bSSunny Srivastava inline void requestRoutesFabricAdapterCollection(App& app)
4443179105bSSunny Srivastava {
4453179105bSSunny Srivastava     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/")
4463179105bSSunny Srivastava         .privileges(redfish::privileges::getFabricAdapterCollection)
4473179105bSSunny Srivastava         .methods(boost::beast::http::verb::get)(
4483179105bSSunny Srivastava             std::bind_front(handleFabricAdapterCollectionGet, std::ref(app)));
4493179105bSSunny Srivastava 
4503179105bSSunny Srivastava     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/")
4513179105bSSunny Srivastava         .privileges(redfish::privileges::headFabricAdapterCollection)
4523179105bSSunny Srivastava         .methods(boost::beast::http::verb::head)(
4533179105bSSunny Srivastava             std::bind_front(handleFabricAdapterCollectionHead, std::ref(app)));
4543179105bSSunny Srivastava }
4553179105bSSunny Srivastava 
4563179105bSSunny Srivastava inline void requestRoutesFabricAdapters(App& app)
4573179105bSSunny Srivastava {
4583179105bSSunny Srivastava     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/<str>/")
4593179105bSSunny Srivastava         .privileges(redfish::privileges::getFabricAdapter)
4603179105bSSunny Srivastava         .methods(boost::beast::http::verb::get)(
4613179105bSSunny Srivastava             std::bind_front(handleFabricAdapterGet, std::ref(app)));
4623179105bSSunny Srivastava 
4633179105bSSunny Srivastava     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/<str>/")
4643179105bSSunny Srivastava         .privileges(redfish::privileges::headFabricAdapter)
4653179105bSSunny Srivastava         .methods(boost::beast::http::verb::head)(
4663179105bSSunny Srivastava             std::bind_front(handleFabricAdapterHead, std::ref(app)));
467be1384e3SMyung Bae 
468be1384e3SMyung Bae     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/<str>/")
469be1384e3SMyung Bae         .privileges(redfish::privileges::patchFabricAdapter)
470be1384e3SMyung Bae         .methods(boost::beast::http::verb::patch)(
471be1384e3SMyung Bae             std::bind_front(handleFabricAdapterPatch, std::ref(app)));
4723179105bSSunny Srivastava }
4733179105bSSunny Srivastava } // namespace redfish
474