xref: /openbmc/bmcweb/features/redfish/lib/fabric_adapters.hpp (revision be1384e3add6a57e1908443e28f49247403a947b)
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"
13*be1384e3SMyung Bae #include "led.hpp"
14d7857201SEd Tanous #include "logging.hpp"
15a8e884fcSEd Tanous #include "query.hpp"
16a8e884fcSEd Tanous #include "registries/privilege_registry.hpp"
173179105bSSunny Srivastava #include "utils/collection.hpp"
186177a301SLakshmi Yadlapati #include "utils/dbus_utils.hpp"
19*be1384e3SMyung Bae #include "utils/json_utils.hpp"
203179105bSSunny Srivastava 
21d7857201SEd Tanous #include <asm-generic/errno.h>
22d7857201SEd Tanous 
23d7857201SEd Tanous #include <boost/beast/http/field.hpp>
24d7857201SEd Tanous #include <boost/beast/http/verb.hpp>
253179105bSSunny Srivastava #include <boost/system/error_code.hpp>
26ef4c65b7SEd Tanous #include <boost/url/format.hpp>
276177a301SLakshmi Yadlapati #include <sdbusplus/unpack_properties.hpp>
283179105bSSunny Srivastava 
293179105bSSunny Srivastava #include <array>
303179105bSSunny Srivastava #include <functional>
313179105bSSunny Srivastava #include <memory>
32*be1384e3SMyung Bae #include <optional>
333179105bSSunny Srivastava #include <string>
343179105bSSunny Srivastava #include <string_view>
35d7857201SEd Tanous #include <utility>
363179105bSSunny Srivastava 
373179105bSSunny Srivastava namespace redfish
383179105bSSunny Srivastava {
393179105bSSunny Srivastava 
40ac106bf6SEd Tanous inline void getFabricAdapterLocation(
41ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
42ac106bf6SEd Tanous     const std::string& serviceName, const std::string& fabricAdapterPath)
4353ffeca5SLakshmi Yadlapati {
44deae6a78SEd Tanous     dbus::utility::getProperty<std::string>(
45deae6a78SEd Tanous         serviceName, fabricAdapterPath,
4653ffeca5SLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Decorator.LocationCode", "LocationCode",
47ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
4853ffeca5SLakshmi Yadlapati                     const std::string& property) {
4953ffeca5SLakshmi Yadlapati             if (ec)
5053ffeca5SLakshmi Yadlapati             {
5153ffeca5SLakshmi Yadlapati                 if (ec.value() != EBADR)
5253ffeca5SLakshmi Yadlapati                 {
5362598e31SEd Tanous                     BMCWEB_LOG_ERROR("DBUS response error for Location");
54ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
5553ffeca5SLakshmi Yadlapati                 }
5653ffeca5SLakshmi Yadlapati                 return;
5753ffeca5SLakshmi Yadlapati             }
5853ffeca5SLakshmi Yadlapati 
59bd79bce8SPatrick Williams             asyncResp->res
60bd79bce8SPatrick Williams                 .jsonValue["Location"]["PartLocation"]["ServiceLabel"] =
6153ffeca5SLakshmi Yadlapati                 property;
6253ffeca5SLakshmi Yadlapati         });
6353ffeca5SLakshmi Yadlapati }
6453ffeca5SLakshmi Yadlapati 
65bd79bce8SPatrick Williams inline void getFabricAdapterAsset(
66bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
67bd79bce8SPatrick Williams     const std::string& serviceName, const std::string& fabricAdapterPath)
686369421dSLakshmi Yadlapati {
69deae6a78SEd Tanous     dbus::utility::getAllProperties(
70deae6a78SEd Tanous         serviceName, fabricAdapterPath,
716369421dSLakshmi Yadlapati         "xyz.openbmc_project.Inventory.Decorator.Asset",
72ac106bf6SEd Tanous         [fabricAdapterPath, asyncResp{asyncResp}](
73ac106bf6SEd Tanous             const boost::system::error_code& ec,
746369421dSLakshmi Yadlapati             const dbus::utility::DBusPropertiesMap& propertiesList) {
756369421dSLakshmi Yadlapati             if (ec)
766369421dSLakshmi Yadlapati             {
776369421dSLakshmi Yadlapati                 if (ec.value() != EBADR)
786369421dSLakshmi Yadlapati                 {
7962598e31SEd Tanous                     BMCWEB_LOG_ERROR("DBUS response error for Properties");
80ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
816369421dSLakshmi Yadlapati                 }
826369421dSLakshmi Yadlapati                 return;
836369421dSLakshmi Yadlapati             }
846369421dSLakshmi Yadlapati 
856369421dSLakshmi Yadlapati             const std::string* serialNumber = nullptr;
866369421dSLakshmi Yadlapati             const std::string* model = nullptr;
876369421dSLakshmi Yadlapati             const std::string* partNumber = nullptr;
886369421dSLakshmi Yadlapati             const std::string* sparePartNumber = nullptr;
896369421dSLakshmi Yadlapati 
906369421dSLakshmi Yadlapati             const bool success = sdbusplus::unpackPropertiesNoThrow(
91bd79bce8SPatrick Williams                 dbus_utils::UnpackErrorPrinter(), propertiesList,
92bd79bce8SPatrick Williams                 "SerialNumber", serialNumber, "Model", model, "PartNumber",
93bd79bce8SPatrick Williams                 partNumber, "SparePartNumber", sparePartNumber);
946369421dSLakshmi Yadlapati 
956369421dSLakshmi Yadlapati             if (!success)
966369421dSLakshmi Yadlapati             {
97ac106bf6SEd Tanous                 messages::internalError(asyncResp->res);
986369421dSLakshmi Yadlapati                 return;
996369421dSLakshmi Yadlapati             }
1006369421dSLakshmi Yadlapati 
1016369421dSLakshmi Yadlapati             if (serialNumber != nullptr)
1026369421dSLakshmi Yadlapati             {
103ac106bf6SEd Tanous                 asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
1046369421dSLakshmi Yadlapati             }
1056369421dSLakshmi Yadlapati 
1066369421dSLakshmi Yadlapati             if (model != nullptr)
1076369421dSLakshmi Yadlapati             {
108ac106bf6SEd Tanous                 asyncResp->res.jsonValue["Model"] = *model;
1096369421dSLakshmi Yadlapati             }
1106369421dSLakshmi Yadlapati 
1116369421dSLakshmi Yadlapati             if (partNumber != nullptr)
1126369421dSLakshmi Yadlapati             {
113ac106bf6SEd Tanous                 asyncResp->res.jsonValue["PartNumber"] = *partNumber;
1146369421dSLakshmi Yadlapati             }
1156369421dSLakshmi Yadlapati 
1166369421dSLakshmi Yadlapati             if (sparePartNumber != nullptr && !sparePartNumber->empty())
1176369421dSLakshmi Yadlapati             {
118ac106bf6SEd Tanous                 asyncResp->res.jsonValue["SparePartNumber"] = *sparePartNumber;
1196369421dSLakshmi Yadlapati             }
1206369421dSLakshmi Yadlapati         });
1216369421dSLakshmi Yadlapati }
1226369421dSLakshmi Yadlapati 
123bd79bce8SPatrick Williams inline void getFabricAdapterState(
124bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
125bd79bce8SPatrick Williams     const std::string& serviceName, const std::string& fabricAdapterPath)
126cd7af44fSLakshmi Yadlapati {
127deae6a78SEd Tanous     dbus::utility::getProperty<bool>(
128deae6a78SEd Tanous         serviceName, fabricAdapterPath, "xyz.openbmc_project.Inventory.Item",
129deae6a78SEd Tanous         "Present",
130ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec, const bool present) {
131cd7af44fSLakshmi Yadlapati             if (ec)
132cd7af44fSLakshmi Yadlapati             {
133cd7af44fSLakshmi Yadlapati                 if (ec.value() != EBADR)
134cd7af44fSLakshmi Yadlapati                 {
13562598e31SEd Tanous                     BMCWEB_LOG_ERROR("DBUS response error for State");
136ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
137cd7af44fSLakshmi Yadlapati                 }
138cd7af44fSLakshmi Yadlapati                 return;
139cd7af44fSLakshmi Yadlapati             }
140cd7af44fSLakshmi Yadlapati 
141cd7af44fSLakshmi Yadlapati             if (!present)
142cd7af44fSLakshmi Yadlapati             {
143539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
144539d8c6bSEd Tanous                     resource::State::Absent;
145cd7af44fSLakshmi Yadlapati             }
146cd7af44fSLakshmi Yadlapati         });
147cd7af44fSLakshmi Yadlapati }
148cd7af44fSLakshmi Yadlapati 
149bd79bce8SPatrick Williams inline void getFabricAdapterHealth(
150bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
151bd79bce8SPatrick Williams     const std::string& serviceName, const std::string& fabricAdapterPath)
1527da847b6SLakshmi Yadlapati {
153deae6a78SEd Tanous     dbus::utility::getProperty<bool>(
154deae6a78SEd Tanous         serviceName, fabricAdapterPath,
1557da847b6SLakshmi Yadlapati         "xyz.openbmc_project.State.Decorator.OperationalStatus", "Functional",
156ac106bf6SEd Tanous         [asyncResp](const boost::system::error_code& ec,
157ac106bf6SEd Tanous                     const bool functional) {
1587da847b6SLakshmi Yadlapati             if (ec)
1597da847b6SLakshmi Yadlapati             {
1607da847b6SLakshmi Yadlapati                 if (ec.value() != EBADR)
1617da847b6SLakshmi Yadlapati                 {
16262598e31SEd Tanous                     BMCWEB_LOG_ERROR("DBUS response error for Health");
163ac106bf6SEd Tanous                     messages::internalError(asyncResp->res);
1647da847b6SLakshmi Yadlapati                 }
1657da847b6SLakshmi Yadlapati                 return;
1667da847b6SLakshmi Yadlapati             }
1677da847b6SLakshmi Yadlapati 
1687da847b6SLakshmi Yadlapati             if (!functional)
1697da847b6SLakshmi Yadlapati             {
170539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["Health"] =
171539d8c6bSEd Tanous                     resource::Health::Critical;
1727da847b6SLakshmi Yadlapati             }
1737da847b6SLakshmi Yadlapati         });
1747da847b6SLakshmi Yadlapati }
1757da847b6SLakshmi Yadlapati 
176bd79bce8SPatrick Williams inline void doAdapterGet(
177bd79bce8SPatrick Williams     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
178bd79bce8SPatrick Williams     const std::string& systemName, const std::string& adapterId,
179bd79bce8SPatrick Williams     const std::string& fabricAdapterPath, const std::string& serviceName)
1803179105bSSunny Srivastava {
181ac106bf6SEd Tanous     asyncResp->res.addHeader(
1823179105bSSunny Srivastava         boost::beast::http::field::link,
1833179105bSSunny Srivastava         "</redfish/v1/JsonSchemas/FabricAdapter/FabricAdapter.json>; rel=describedby");
184ac106bf6SEd Tanous     asyncResp->res.jsonValue["@odata.type"] =
185ac106bf6SEd Tanous         "#FabricAdapter.v1_4_0.FabricAdapter";
186ac106bf6SEd Tanous     asyncResp->res.jsonValue["Name"] = "Fabric Adapter";
187ac106bf6SEd Tanous     asyncResp->res.jsonValue["Id"] = adapterId;
188ac106bf6SEd Tanous     asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
189ef4c65b7SEd Tanous         "/redfish/v1/Systems/{}/FabricAdapters/{}", systemName, adapterId);
19053ffeca5SLakshmi Yadlapati 
191539d8c6bSEd Tanous     asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
192539d8c6bSEd Tanous     asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK;
193cd7af44fSLakshmi Yadlapati 
194ac106bf6SEd Tanous     getFabricAdapterLocation(asyncResp, serviceName, fabricAdapterPath);
195ac106bf6SEd Tanous     getFabricAdapterAsset(asyncResp, serviceName, fabricAdapterPath);
196ac106bf6SEd Tanous     getFabricAdapterState(asyncResp, serviceName, fabricAdapterPath);
197ac106bf6SEd Tanous     getFabricAdapterHealth(asyncResp, serviceName, fabricAdapterPath);
198*be1384e3SMyung Bae     getLocationIndicatorActive(asyncResp, fabricAdapterPath);
1993179105bSSunny Srivastava }
2003179105bSSunny Srivastava 
20178c90203SMyung Bae inline void afterGetValidFabricAdapterPath(
20278c90203SMyung Bae     const std::string& adapterId,
20378c90203SMyung Bae     std::function<void(const boost::system::error_code&,
20478c90203SMyung Bae                        const std::string& fabricAdapterPath,
20578c90203SMyung Bae                        const std::string& serviceName)>& callback,
20678c90203SMyung Bae     const boost::system::error_code& ec,
20778c90203SMyung Bae     const dbus::utility::MapperGetSubTreeResponse& subtree)
20878c90203SMyung Bae {
20978c90203SMyung Bae     std::string fabricAdapterPath;
21078c90203SMyung Bae     std::string serviceName;
21178c90203SMyung Bae     if (ec)
21278c90203SMyung Bae     {
21378c90203SMyung Bae         callback(ec, fabricAdapterPath, serviceName);
21478c90203SMyung Bae         return;
21578c90203SMyung Bae     }
21678c90203SMyung Bae 
21778c90203SMyung Bae     for (const auto& [adapterPath, serviceMap] : subtree)
2183179105bSSunny Srivastava     {
2193179105bSSunny Srivastava         std::string fabricAdapterName =
2203179105bSSunny Srivastava             sdbusplus::message::object_path(adapterPath).filename();
22178c90203SMyung Bae         if (fabricAdapterName == adapterId)
22278c90203SMyung Bae         {
22378c90203SMyung Bae             fabricAdapterPath = adapterPath;
22478c90203SMyung Bae             serviceName = serviceMap.begin()->first;
22578c90203SMyung Bae             break;
22678c90203SMyung Bae         }
22778c90203SMyung Bae     }
22878c90203SMyung Bae     callback(ec, fabricAdapterPath, serviceName);
2293179105bSSunny Srivastava }
2303179105bSSunny Srivastava 
2313179105bSSunny Srivastava inline void getValidFabricAdapterPath(
23278c90203SMyung Bae     const std::string& adapterId,
23378c90203SMyung Bae     std::function<void(const boost::system::error_code& ec,
23478c90203SMyung Bae                        const std::string& fabricAdapterPath,
2353179105bSSunny Srivastava                        const std::string& serviceName)>&& callback)
2363179105bSSunny Srivastava {
2373179105bSSunny Srivastava     constexpr std::array<std::string_view, 1> interfaces{
2383179105bSSunny Srivastava         "xyz.openbmc_project.Inventory.Item.FabricAdapter"};
23978c90203SMyung Bae     dbus::utility::getSubTree("/xyz/openbmc_project/inventory", 0, interfaces,
24078c90203SMyung Bae                               std::bind_front(afterGetValidFabricAdapterPath,
24178c90203SMyung Bae                                               adapterId, std::move(callback)));
24278c90203SMyung Bae }
2433179105bSSunny Srivastava 
24478c90203SMyung Bae inline void afterHandleFabricAdapterGet(
24578c90203SMyung Bae     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
24678c90203SMyung Bae     const std::string& systemName, const std::string& adapterId,
24778c90203SMyung Bae     const boost::system::error_code& ec, const std::string& fabricAdapterPath,
24878c90203SMyung Bae     const std::string& serviceName)
24978c90203SMyung Bae {
2503179105bSSunny Srivastava     if (ec)
2513179105bSSunny Srivastava     {
25278c90203SMyung Bae         if (ec.value() == boost::system::errc::io_error)
25378c90203SMyung Bae         {
25478c90203SMyung Bae             messages::resourceNotFound(asyncResp->res, "FabricAdapter",
25578c90203SMyung Bae                                        adapterId);
2563179105bSSunny Srivastava             return;
2573179105bSSunny Srivastava         }
25878c90203SMyung Bae 
25978c90203SMyung Bae         BMCWEB_LOG_ERROR("DBus method call failed with error {}", ec.value());
26078c90203SMyung Bae         messages::internalError(asyncResp->res);
2613179105bSSunny Srivastava         return;
2623179105bSSunny Srivastava     }
26378c90203SMyung Bae     if (fabricAdapterPath.empty() || serviceName.empty())
26478c90203SMyung Bae     {
26562598e31SEd Tanous         BMCWEB_LOG_WARNING("Adapter not found");
266ac106bf6SEd Tanous         messages::resourceNotFound(asyncResp->res, "FabricAdapter", adapterId);
26778c90203SMyung Bae         return;
26878c90203SMyung Bae     }
26978c90203SMyung Bae     doAdapterGet(asyncResp, systemName, adapterId, fabricAdapterPath,
27078c90203SMyung Bae                  serviceName);
2713179105bSSunny Srivastava }
2723179105bSSunny Srivastava 
273bd79bce8SPatrick Williams inline void handleFabricAdapterGet(
274bd79bce8SPatrick Williams     App& app, const crow::Request& req,
275ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
276bd79bce8SPatrick Williams     const std::string& systemName, const std::string& adapterId)
2773179105bSSunny Srivastava {
278ac106bf6SEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2793179105bSSunny Srivastava     {
2803179105bSSunny Srivastava         return;
2813179105bSSunny Srivastava     }
28225b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
2837f3e84a1SEd Tanous     {
2847f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
2857f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2867f3e84a1SEd Tanous                                    systemName);
2877f3e84a1SEd Tanous         return;
2887f3e84a1SEd Tanous     }
289253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
29078c90203SMyung Bae     {
29178c90203SMyung Bae         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
29278c90203SMyung Bae                                    systemName);
29378c90203SMyung Bae         return;
29478c90203SMyung Bae     }
2953179105bSSunny Srivastava     getValidFabricAdapterPath(
29678c90203SMyung Bae         adapterId, std::bind_front(afterHandleFabricAdapterGet, asyncResp,
29778c90203SMyung Bae                                    systemName, adapterId));
2983179105bSSunny Srivastava }
2993179105bSSunny Srivastava 
300*be1384e3SMyung Bae inline void afterHandleFabricAdapterPatch(
301*be1384e3SMyung Bae     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
302*be1384e3SMyung Bae     const std::string& adapterId, std::optional<bool> locationIndicatorActive,
303*be1384e3SMyung Bae     const boost::system::error_code& ec, const std::string& fabricAdapterPath,
304*be1384e3SMyung Bae     const std::string& serviceName)
305*be1384e3SMyung Bae {
306*be1384e3SMyung Bae     if (ec)
307*be1384e3SMyung Bae     {
308*be1384e3SMyung Bae         if (ec.value() == boost::system::errc::io_error)
309*be1384e3SMyung Bae         {
310*be1384e3SMyung Bae             messages::resourceNotFound(asyncResp->res, "FabricAdapter",
311*be1384e3SMyung Bae                                        adapterId);
312*be1384e3SMyung Bae             return;
313*be1384e3SMyung Bae         }
314*be1384e3SMyung Bae 
315*be1384e3SMyung Bae         BMCWEB_LOG_ERROR("DBus method call failed with error {}", ec.value());
316*be1384e3SMyung Bae         messages::internalError(asyncResp->res);
317*be1384e3SMyung Bae         return;
318*be1384e3SMyung Bae     }
319*be1384e3SMyung Bae     if (fabricAdapterPath.empty() || serviceName.empty())
320*be1384e3SMyung Bae     {
321*be1384e3SMyung Bae         BMCWEB_LOG_WARNING("Adapter {} not found", adapterId);
322*be1384e3SMyung Bae         messages::resourceNotFound(asyncResp->res, "FabricAdapter", adapterId);
323*be1384e3SMyung Bae         return;
324*be1384e3SMyung Bae     }
325*be1384e3SMyung Bae 
326*be1384e3SMyung Bae     if (locationIndicatorActive)
327*be1384e3SMyung Bae     {
328*be1384e3SMyung Bae         setLocationIndicatorActive(asyncResp, fabricAdapterPath,
329*be1384e3SMyung Bae                                    *locationIndicatorActive);
330*be1384e3SMyung Bae     }
331*be1384e3SMyung Bae }
332*be1384e3SMyung Bae 
333*be1384e3SMyung Bae inline void handleFabricAdapterPatch(
334*be1384e3SMyung Bae     App& app, const crow::Request& req,
335*be1384e3SMyung Bae     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
336*be1384e3SMyung Bae     const std::string& systemName, const std::string& adapterId)
337*be1384e3SMyung Bae {
338*be1384e3SMyung Bae     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
339*be1384e3SMyung Bae     {
340*be1384e3SMyung Bae         return;
341*be1384e3SMyung Bae     }
342*be1384e3SMyung Bae     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
343*be1384e3SMyung Bae     {
344*be1384e3SMyung Bae         // Option currently returns no systems.  TBD
345*be1384e3SMyung Bae         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
346*be1384e3SMyung Bae                                    systemName);
347*be1384e3SMyung Bae         return;
348*be1384e3SMyung Bae     }
349*be1384e3SMyung Bae     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
350*be1384e3SMyung Bae     {
351*be1384e3SMyung Bae         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
352*be1384e3SMyung Bae                                    systemName);
353*be1384e3SMyung Bae         return;
354*be1384e3SMyung Bae     }
355*be1384e3SMyung Bae 
356*be1384e3SMyung Bae     std::optional<bool> locationIndicatorActive;
357*be1384e3SMyung Bae 
358*be1384e3SMyung Bae     if (!json_util::readJsonPatch(req, asyncResp->res,
359*be1384e3SMyung Bae                                   "LocationIndicatorActive",
360*be1384e3SMyung Bae                                   locationIndicatorActive))
361*be1384e3SMyung Bae     {
362*be1384e3SMyung Bae         return;
363*be1384e3SMyung Bae     }
364*be1384e3SMyung Bae 
365*be1384e3SMyung Bae     getValidFabricAdapterPath(
366*be1384e3SMyung Bae         adapterId, std::bind_front(afterHandleFabricAdapterPatch, asyncResp,
367*be1384e3SMyung Bae                                    adapterId, locationIndicatorActive));
368*be1384e3SMyung Bae }
369*be1384e3SMyung Bae 
3703179105bSSunny Srivastava inline void handleFabricAdapterCollectionGet(
3713179105bSSunny Srivastava     crow::App& app, const crow::Request& req,
372ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3733179105bSSunny Srivastava     const std::string& systemName)
3743179105bSSunny Srivastava {
375ac106bf6SEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3763179105bSSunny Srivastava     {
3773179105bSSunny Srivastava         return;
3783179105bSSunny Srivastava     }
37925b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
3807f3e84a1SEd Tanous     {
3817f3e84a1SEd Tanous         // Option currently returns no systems. TBD
3827f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3837f3e84a1SEd Tanous                                    systemName);
3847f3e84a1SEd Tanous         return;
3857f3e84a1SEd Tanous     }
386253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
3873179105bSSunny Srivastava     {
388ac106bf6SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
389ac106bf6SEd Tanous                                    systemName);
3903179105bSSunny Srivastava         return;
3913179105bSSunny Srivastava     }
3923179105bSSunny Srivastava 
393ac106bf6SEd Tanous     asyncResp->res.addHeader(
3943179105bSSunny Srivastava         boost::beast::http::field::link,
3953179105bSSunny Srivastava         "</redfish/v1/JsonSchemas/FabricAdapterCollection/FabricAdapterCollection.json>; rel=describedby");
396ac106bf6SEd Tanous     asyncResp->res.jsonValue["@odata.type"] =
3973179105bSSunny Srivastava         "#FabricAdapterCollection.FabricAdapterCollection";
398ac106bf6SEd Tanous     asyncResp->res.jsonValue["Name"] = "Fabric Adapter Collection";
399ac106bf6SEd Tanous     asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
400ef4c65b7SEd Tanous         "/redfish/v1/Systems/{}/FabricAdapters", systemName);
4013179105bSSunny Srivastava 
4023179105bSSunny Srivastava     constexpr std::array<std::string_view, 1> interfaces{
4033179105bSSunny Srivastava         "xyz.openbmc_project.Inventory.Item.FabricAdapter"};
4043179105bSSunny Srivastava     collection_util::getCollectionMembers(
405ac106bf6SEd Tanous         asyncResp,
406253f11b8SEd Tanous         boost::urls::format("/redfish/v1/Systems/{}/FabricAdapters",
407253f11b8SEd Tanous                             BMCWEB_REDFISH_SYSTEM_URI_NAME),
40836b5f1edSLakshmi Yadlapati         interfaces, "/xyz/openbmc_project/inventory");
4093179105bSSunny Srivastava }
4103179105bSSunny Srivastava 
4113179105bSSunny Srivastava inline void handleFabricAdapterCollectionHead(
4123179105bSSunny Srivastava     crow::App& app, const crow::Request& req,
413ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
4143179105bSSunny Srivastava     const std::string& systemName)
4153179105bSSunny Srivastava {
416ac106bf6SEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
4173179105bSSunny Srivastava     {
4183179105bSSunny Srivastava         return;
4193179105bSSunny Srivastava     }
42025b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
4217f3e84a1SEd Tanous     {
4227f3e84a1SEd Tanous         // Option currently returns no systems.  TBD
4237f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
4247f3e84a1SEd Tanous                                    systemName);
4257f3e84a1SEd Tanous         return;
4267f3e84a1SEd Tanous     }
427253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
4283179105bSSunny Srivastava     {
429ac106bf6SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
430ac106bf6SEd Tanous                                    systemName);
4313179105bSSunny Srivastava         return;
4323179105bSSunny Srivastava     }
433ac106bf6SEd Tanous     asyncResp->res.addHeader(
4343179105bSSunny Srivastava         boost::beast::http::field::link,
4353179105bSSunny Srivastava         "</redfish/v1/JsonSchemas/FabricAdapterCollection/FabricAdapterCollection.json>; rel=describedby");
4363179105bSSunny Srivastava }
4373179105bSSunny Srivastava 
43878c90203SMyung Bae inline void afterHandleFabricAdapterHead(
43978c90203SMyung Bae     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
44078c90203SMyung Bae     const std::string& adapterId, const boost::system::error_code& ec,
44178c90203SMyung Bae     const std::string& fabricAdapterPath, const std::string& serviceName)
44278c90203SMyung Bae {
44378c90203SMyung Bae     if (ec)
44478c90203SMyung Bae     {
44578c90203SMyung Bae         if (ec.value() == boost::system::errc::io_error)
44678c90203SMyung Bae         {
44778c90203SMyung Bae             messages::resourceNotFound(asyncResp->res, "FabricAdapter",
44878c90203SMyung Bae                                        adapterId);
44978c90203SMyung Bae             return;
45078c90203SMyung Bae         }
45178c90203SMyung Bae 
45278c90203SMyung Bae         BMCWEB_LOG_ERROR("DBus method call failed with error {}", ec.value());
45378c90203SMyung Bae         messages::internalError(asyncResp->res);
45478c90203SMyung Bae         return;
45578c90203SMyung Bae     }
45678c90203SMyung Bae     if (fabricAdapterPath.empty() || serviceName.empty())
45778c90203SMyung Bae     {
45878c90203SMyung Bae         BMCWEB_LOG_WARNING("Adapter not found");
45978c90203SMyung Bae         messages::resourceNotFound(asyncResp->res, "FabricAdapter", adapterId);
46078c90203SMyung Bae         return;
46178c90203SMyung Bae     }
46278c90203SMyung Bae     asyncResp->res.addHeader(
46378c90203SMyung Bae         boost::beast::http::field::link,
46478c90203SMyung Bae         "</redfish/v1/JsonSchemas/FabricAdapter/FabricAdapter.json>; rel=describedby");
46578c90203SMyung Bae }
46678c90203SMyung Bae 
467bd79bce8SPatrick Williams inline void handleFabricAdapterHead(
468bd79bce8SPatrick Williams     crow::App& app, const crow::Request& req,
469ac106bf6SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
470bd79bce8SPatrick Williams     const std::string& systemName, const std::string& adapterId)
4713179105bSSunny Srivastava {
472ac106bf6SEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
4733179105bSSunny Srivastava     {
4743179105bSSunny Srivastava         return;
4753179105bSSunny Srivastava     }
4763179105bSSunny Srivastava 
47725b54dbaSEd Tanous     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
4787f3e84a1SEd Tanous     {
4797f3e84a1SEd Tanous         // Option currently returns no systems. TBD
4807f3e84a1SEd Tanous         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
4817f3e84a1SEd Tanous                                    systemName);
4827f3e84a1SEd Tanous         return;
4837f3e84a1SEd Tanous     }
484253f11b8SEd Tanous     if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
48578c90203SMyung Bae     {
48678c90203SMyung Bae         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
48778c90203SMyung Bae                                    systemName);
48878c90203SMyung Bae         return;
48978c90203SMyung Bae     }
49078c90203SMyung Bae     getValidFabricAdapterPath(
49178c90203SMyung Bae         adapterId,
49278c90203SMyung Bae         std::bind_front(afterHandleFabricAdapterHead, asyncResp, adapterId));
4933179105bSSunny Srivastava }
4943179105bSSunny Srivastava 
4953179105bSSunny Srivastava inline void requestRoutesFabricAdapterCollection(App& app)
4963179105bSSunny Srivastava {
4973179105bSSunny Srivastava     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/")
4983179105bSSunny Srivastava         .privileges(redfish::privileges::getFabricAdapterCollection)
4993179105bSSunny Srivastava         .methods(boost::beast::http::verb::get)(
5003179105bSSunny Srivastava             std::bind_front(handleFabricAdapterCollectionGet, std::ref(app)));
5013179105bSSunny Srivastava 
5023179105bSSunny Srivastava     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/")
5033179105bSSunny Srivastava         .privileges(redfish::privileges::headFabricAdapterCollection)
5043179105bSSunny Srivastava         .methods(boost::beast::http::verb::head)(
5053179105bSSunny Srivastava             std::bind_front(handleFabricAdapterCollectionHead, std::ref(app)));
5063179105bSSunny Srivastava }
5073179105bSSunny Srivastava 
5083179105bSSunny Srivastava inline void requestRoutesFabricAdapters(App& app)
5093179105bSSunny Srivastava {
5103179105bSSunny Srivastava     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/<str>/")
5113179105bSSunny Srivastava         .privileges(redfish::privileges::getFabricAdapter)
5123179105bSSunny Srivastava         .methods(boost::beast::http::verb::get)(
5133179105bSSunny Srivastava             std::bind_front(handleFabricAdapterGet, std::ref(app)));
5143179105bSSunny Srivastava 
5153179105bSSunny Srivastava     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/<str>/")
5163179105bSSunny Srivastava         .privileges(redfish::privileges::headFabricAdapter)
5173179105bSSunny Srivastava         .methods(boost::beast::http::verb::head)(
5183179105bSSunny Srivastava             std::bind_front(handleFabricAdapterHead, std::ref(app)));
519*be1384e3SMyung Bae 
520*be1384e3SMyung Bae     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/<str>/")
521*be1384e3SMyung Bae         .privileges(redfish::privileges::patchFabricAdapter)
522*be1384e3SMyung Bae         .methods(boost::beast::http::verb::patch)(
523*be1384e3SMyung Bae             std::bind_front(handleFabricAdapterPatch, std::ref(app)));
5243179105bSSunny Srivastava }
5253179105bSSunny Srivastava } // namespace redfish
526