xref: /openbmc/bmcweb/features/redfish/lib/cable.hpp (revision 3ccb3adb9a14783f6bef601506de9f8bcae22d51)
19c929beaSShantappa Teekappanavar #pragma once
27a1dbc48SGeorge Liu 
37a1dbc48SGeorge Liu #include "dbus_utility.hpp"
4*3ccb3adbSEd Tanous #include "query.hpp"
5*3ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
6*3ccb3adbSEd Tanous #include "utils/collection.hpp"
7*3ccb3adbSEd Tanous #include "utils/dbus_utils.hpp"
8*3ccb3adbSEd Tanous #include "utils/json_utils.hpp"
97a1dbc48SGeorge Liu 
1089474494SKrzysztof Grobelny #include <sdbusplus/asio/property.hpp>
1189474494SKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
129c929beaSShantappa Teekappanavar 
137a1dbc48SGeorge Liu #include <array>
147a1dbc48SGeorge Liu #include <string_view>
157a1dbc48SGeorge Liu 
169c929beaSShantappa Teekappanavar namespace redfish
179c929beaSShantappa Teekappanavar {
189c929beaSShantappa Teekappanavar /**
199c929beaSShantappa Teekappanavar  * @brief Fill cable specific properties.
209c929beaSShantappa Teekappanavar  * @param[in,out]   resp        HTTP response.
219c929beaSShantappa Teekappanavar  * @param[in]       ec          Error code corresponding to Async method call.
229c929beaSShantappa Teekappanavar  * @param[in]       properties  List of Cable Properties key/value pairs.
239c929beaSShantappa Teekappanavar  */
249c929beaSShantappa Teekappanavar inline void
259c929beaSShantappa Teekappanavar     fillCableProperties(crow::Response& resp,
269c929beaSShantappa Teekappanavar                         const boost::system::error_code ec,
279c929beaSShantappa Teekappanavar                         const dbus::utility::DBusPropertiesMap& properties)
289c929beaSShantappa Teekappanavar {
299c929beaSShantappa Teekappanavar     if (ec)
309c929beaSShantappa Teekappanavar     {
319c929beaSShantappa Teekappanavar         BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
329c929beaSShantappa Teekappanavar         messages::internalError(resp);
339c929beaSShantappa Teekappanavar         return;
349c929beaSShantappa Teekappanavar     }
359c929beaSShantappa Teekappanavar 
3689474494SKrzysztof Grobelny     const std::string* cableTypeDescription = nullptr;
3789474494SKrzysztof Grobelny     const double* length = nullptr;
3889474494SKrzysztof Grobelny 
3989474494SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
4089474494SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "CableTypeDescription",
4189474494SKrzysztof Grobelny         cableTypeDescription, "Length", length);
4289474494SKrzysztof Grobelny 
4389474494SKrzysztof Grobelny     if (!success)
449c929beaSShantappa Teekappanavar     {
459c929beaSShantappa Teekappanavar         messages::internalError(resp);
469c929beaSShantappa Teekappanavar         return;
479c929beaSShantappa Teekappanavar     }
4889474494SKrzysztof Grobelny 
4989474494SKrzysztof Grobelny     if (cableTypeDescription != nullptr)
5089474494SKrzysztof Grobelny     {
519c929beaSShantappa Teekappanavar         resp.jsonValue["CableType"] = *cableTypeDescription;
529c929beaSShantappa Teekappanavar     }
539c929beaSShantappa Teekappanavar 
5489474494SKrzysztof Grobelny     if (length != nullptr)
559c929beaSShantappa Teekappanavar     {
5689474494SKrzysztof Grobelny         if (!std::isfinite(*length))
579c929beaSShantappa Teekappanavar         {
58043360d0SShantappa Teekappanavar             // Cable length is NaN by default, do not throw an error
59043360d0SShantappa Teekappanavar             if (!std::isnan(*length))
6089474494SKrzysztof Grobelny             {
619c929beaSShantappa Teekappanavar                 messages::internalError(resp);
629c929beaSShantappa Teekappanavar                 return;
639c929beaSShantappa Teekappanavar             }
64043360d0SShantappa Teekappanavar         }
65043360d0SShantappa Teekappanavar         else
66043360d0SShantappa Teekappanavar         {
6789474494SKrzysztof Grobelny             resp.jsonValue["LengthMeters"] = *length;
689c929beaSShantappa Teekappanavar         }
699c929beaSShantappa Teekappanavar     }
70043360d0SShantappa Teekappanavar }
719c929beaSShantappa Teekappanavar 
729c929beaSShantappa Teekappanavar /**
739c929beaSShantappa Teekappanavar  * @brief Api to get Cable properties.
749c929beaSShantappa Teekappanavar  * @param[in,out]   asyncResp       Async HTTP response.
759c929beaSShantappa Teekappanavar  * @param[in]       cableObjectPath Object path of the Cable.
769c929beaSShantappa Teekappanavar  * @param[in]       serviceMap      A map to hold Service and corresponding
779c929beaSShantappa Teekappanavar  * interface list for the given cable id.
789c929beaSShantappa Teekappanavar  */
799c929beaSShantappa Teekappanavar inline void
809c929beaSShantappa Teekappanavar     getCableProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
819c929beaSShantappa Teekappanavar                        const std::string& cableObjectPath,
829c929beaSShantappa Teekappanavar                        const dbus::utility::MapperServiceMap& serviceMap)
839c929beaSShantappa Teekappanavar {
849c929beaSShantappa Teekappanavar     BMCWEB_LOG_DEBUG << "Get Properties for cable " << cableObjectPath;
859c929beaSShantappa Teekappanavar 
869c929beaSShantappa Teekappanavar     for (const auto& [service, interfaces] : serviceMap)
879c929beaSShantappa Teekappanavar     {
889c929beaSShantappa Teekappanavar         for (const auto& interface : interfaces)
899c929beaSShantappa Teekappanavar         {
909c929beaSShantappa Teekappanavar             if (interface != "xyz.openbmc_project.Inventory.Item.Cable")
919c929beaSShantappa Teekappanavar             {
929c929beaSShantappa Teekappanavar                 continue;
939c929beaSShantappa Teekappanavar             }
949c929beaSShantappa Teekappanavar 
9589474494SKrzysztof Grobelny             sdbusplus::asio::getAllProperties(
9689474494SKrzysztof Grobelny                 *crow::connections::systemBus, service, cableObjectPath,
9789474494SKrzysztof Grobelny                 interface,
989c929beaSShantappa Teekappanavar                 [asyncResp](
999c929beaSShantappa Teekappanavar                     const boost::system::error_code ec,
1009c929beaSShantappa Teekappanavar                     const dbus::utility::DBusPropertiesMap& properties) {
1019c929beaSShantappa Teekappanavar                 fillCableProperties(asyncResp->res, ec, properties);
10289474494SKrzysztof Grobelny                 });
1039c929beaSShantappa Teekappanavar         }
1049c929beaSShantappa Teekappanavar     }
1059c929beaSShantappa Teekappanavar }
1069c929beaSShantappa Teekappanavar 
1079c929beaSShantappa Teekappanavar /**
1089c929beaSShantappa Teekappanavar  * The Cable schema
1099c929beaSShantappa Teekappanavar  */
1109c929beaSShantappa Teekappanavar inline void requestRoutesCable(App& app)
1119c929beaSShantappa Teekappanavar {
1129c929beaSShantappa Teekappanavar     BMCWEB_ROUTE(app, "/redfish/v1/Cables/<str>/")
1139c929beaSShantappa Teekappanavar         .privileges(redfish::privileges::getCable)
1149c929beaSShantappa Teekappanavar         .methods(boost::beast::http::verb::get)(
11545ca1b86SEd Tanous             [&app](const crow::Request& req,
1169c929beaSShantappa Teekappanavar                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1179c929beaSShantappa Teekappanavar                    const std::string& cableId) {
1183ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
11945ca1b86SEd Tanous         {
12045ca1b86SEd Tanous             return;
12145ca1b86SEd Tanous         }
1229c929beaSShantappa Teekappanavar         BMCWEB_LOG_DEBUG << "Cable Id: " << cableId;
1239c929beaSShantappa Teekappanavar         auto respHandler =
1249c929beaSShantappa Teekappanavar             [asyncResp,
1259c929beaSShantappa Teekappanavar              cableId](const boost::system::error_code ec,
126002d39b4SEd Tanous                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
1279c929beaSShantappa Teekappanavar             if (ec.value() == EBADR)
1289c929beaSShantappa Teekappanavar             {
129d8a5d5d8SJiaqing Zhao                 messages::resourceNotFound(asyncResp->res, "Cable", cableId);
1309c929beaSShantappa Teekappanavar                 return;
1319c929beaSShantappa Teekappanavar             }
1329c929beaSShantappa Teekappanavar 
1339c929beaSShantappa Teekappanavar             if (ec)
1349c929beaSShantappa Teekappanavar             {
1359c929beaSShantappa Teekappanavar                 BMCWEB_LOG_ERROR << "DBUS response error " << ec;
1369c929beaSShantappa Teekappanavar                 messages::internalError(asyncResp->res);
1379c929beaSShantappa Teekappanavar                 return;
1389c929beaSShantappa Teekappanavar             }
1399c929beaSShantappa Teekappanavar 
1409c929beaSShantappa Teekappanavar             for (const auto& [objectPath, serviceMap] : subtree)
1419c929beaSShantappa Teekappanavar             {
1429c929beaSShantappa Teekappanavar                 sdbusplus::message::object_path path(objectPath);
1439c929beaSShantappa Teekappanavar                 if (path.filename() != cableId)
1449c929beaSShantappa Teekappanavar                 {
1459c929beaSShantappa Teekappanavar                     continue;
1469c929beaSShantappa Teekappanavar                 }
1479c929beaSShantappa Teekappanavar 
148002d39b4SEd Tanous                 asyncResp->res.jsonValue["@odata.type"] = "#Cable.v1_0_0.Cable";
1499c929beaSShantappa Teekappanavar                 asyncResp->res.jsonValue["@odata.id"] =
1509c929beaSShantappa Teekappanavar                     "/redfish/v1/Cables/" + cableId;
1519c929beaSShantappa Teekappanavar                 asyncResp->res.jsonValue["Id"] = cableId;
1529c929beaSShantappa Teekappanavar                 asyncResp->res.jsonValue["Name"] = "Cable";
1539c929beaSShantappa Teekappanavar 
154002d39b4SEd Tanous                 getCableProperties(asyncResp, objectPath, serviceMap);
1559c929beaSShantappa Teekappanavar                 return;
1569c929beaSShantappa Teekappanavar             }
157002d39b4SEd Tanous             messages::resourceNotFound(asyncResp->res, "Cable", cableId);
1589c929beaSShantappa Teekappanavar         };
1599c929beaSShantappa Teekappanavar 
1609c929beaSShantappa Teekappanavar         crow::connections::systemBus->async_method_call(
1619c929beaSShantappa Teekappanavar             respHandler, "xyz.openbmc_project.ObjectMapper",
1629c929beaSShantappa Teekappanavar             "/xyz/openbmc_project/object_mapper",
1639c929beaSShantappa Teekappanavar             "xyz.openbmc_project.ObjectMapper", "GetSubTree",
1649c929beaSShantappa Teekappanavar             "/xyz/openbmc_project/inventory", 0,
1659c929beaSShantappa Teekappanavar             std::array<const char*, 1>{
1669c929beaSShantappa Teekappanavar                 "xyz.openbmc_project.Inventory.Item.Cable"});
1679c929beaSShantappa Teekappanavar         });
1689c929beaSShantappa Teekappanavar }
1699c929beaSShantappa Teekappanavar 
1709c929beaSShantappa Teekappanavar /**
1719c929beaSShantappa Teekappanavar  * Collection of Cable resource instances
1729c929beaSShantappa Teekappanavar  */
1739c929beaSShantappa Teekappanavar inline void requestRoutesCableCollection(App& app)
1749c929beaSShantappa Teekappanavar {
1759c929beaSShantappa Teekappanavar     BMCWEB_ROUTE(app, "/redfish/v1/Cables/")
1769c929beaSShantappa Teekappanavar         .privileges(redfish::privileges::getCableCollection)
1779c929beaSShantappa Teekappanavar         .methods(boost::beast::http::verb::get)(
17845ca1b86SEd Tanous             [&app](const crow::Request& req,
1799c929beaSShantappa Teekappanavar                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
1803ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
18145ca1b86SEd Tanous         {
18245ca1b86SEd Tanous             return;
18345ca1b86SEd Tanous         }
1849c929beaSShantappa Teekappanavar         asyncResp->res.jsonValue["@odata.type"] =
1859c929beaSShantappa Teekappanavar             "#CableCollection.CableCollection";
1869c929beaSShantappa Teekappanavar         asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Cables";
1879c929beaSShantappa Teekappanavar         asyncResp->res.jsonValue["Name"] = "Cable Collection";
188002d39b4SEd Tanous         asyncResp->res.jsonValue["Description"] = "Collection of Cable Entries";
1897a1dbc48SGeorge Liu         constexpr std::array<std::string_view, 1> interfaces{
1907a1dbc48SGeorge Liu             "xyz.openbmc_project.Inventory.Item.Cable"};
1919c929beaSShantappa Teekappanavar         collection_util::getCollectionMembers(
1927a1dbc48SGeorge Liu             asyncResp, boost::urls::url("/redfish/v1/Cables"), interfaces);
1939c929beaSShantappa Teekappanavar         });
1949c929beaSShantappa Teekappanavar }
1959c929beaSShantappa Teekappanavar 
1969c929beaSShantappa Teekappanavar } // namespace redfish
197