xref: /openbmc/bmcweb/features/redfish/lib/cable.hpp (revision 539d8c6bc399e516d39bcaa18262cf206f4c1035)
19c929beaSShantappa Teekappanavar #pragma once
27a1dbc48SGeorge Liu 
37a1dbc48SGeorge Liu #include "dbus_utility.hpp"
4*539d8c6bSEd Tanous #include "generated/enums/resource.hpp"
53ccb3adbSEd Tanous #include "query.hpp"
63ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
73ccb3adbSEd Tanous #include "utils/collection.hpp"
83ccb3adbSEd Tanous #include "utils/dbus_utils.hpp"
93ccb3adbSEd Tanous #include "utils/json_utils.hpp"
107a1dbc48SGeorge Liu 
11e99073f5SGeorge Liu #include <boost/system/error_code.hpp>
12ef4c65b7SEd Tanous #include <boost/url/format.hpp>
1389474494SKrzysztof Grobelny #include <sdbusplus/asio/property.hpp>
1489474494SKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
159c929beaSShantappa Teekappanavar 
167a1dbc48SGeorge Liu #include <array>
177a1dbc48SGeorge Liu #include <string_view>
187a1dbc48SGeorge Liu 
199c929beaSShantappa Teekappanavar namespace redfish
209c929beaSShantappa Teekappanavar {
219c929beaSShantappa Teekappanavar /**
229c929beaSShantappa Teekappanavar  * @brief Fill cable specific properties.
239c929beaSShantappa Teekappanavar  * @param[in,out]   resp        HTTP response.
249c929beaSShantappa Teekappanavar  * @param[in]       ec          Error code corresponding to Async method call.
259c929beaSShantappa Teekappanavar  * @param[in]       properties  List of Cable Properties key/value pairs.
269c929beaSShantappa Teekappanavar  */
279c929beaSShantappa Teekappanavar inline void
289c929beaSShantappa Teekappanavar     fillCableProperties(crow::Response& resp,
295e7e2dc5SEd Tanous                         const boost::system::error_code& ec,
309c929beaSShantappa Teekappanavar                         const dbus::utility::DBusPropertiesMap& properties)
319c929beaSShantappa Teekappanavar {
329c929beaSShantappa Teekappanavar     if (ec)
339c929beaSShantappa Teekappanavar     {
34f933a6a0SGunnar Mills         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
359c929beaSShantappa Teekappanavar         messages::internalError(resp);
369c929beaSShantappa Teekappanavar         return;
379c929beaSShantappa Teekappanavar     }
389c929beaSShantappa Teekappanavar 
3989474494SKrzysztof Grobelny     const std::string* cableTypeDescription = nullptr;
4089474494SKrzysztof Grobelny     const double* length = nullptr;
4189474494SKrzysztof Grobelny 
4289474494SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
4389474494SKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "CableTypeDescription",
4489474494SKrzysztof Grobelny         cableTypeDescription, "Length", length);
4589474494SKrzysztof Grobelny 
4689474494SKrzysztof Grobelny     if (!success)
479c929beaSShantappa Teekappanavar     {
489c929beaSShantappa Teekappanavar         messages::internalError(resp);
499c929beaSShantappa Teekappanavar         return;
509c929beaSShantappa Teekappanavar     }
5189474494SKrzysztof Grobelny 
5289474494SKrzysztof Grobelny     if (cableTypeDescription != nullptr)
5389474494SKrzysztof Grobelny     {
549c929beaSShantappa Teekappanavar         resp.jsonValue["CableType"] = *cableTypeDescription;
559c929beaSShantappa Teekappanavar     }
569c929beaSShantappa Teekappanavar 
5789474494SKrzysztof Grobelny     if (length != nullptr)
589c929beaSShantappa Teekappanavar     {
5989474494SKrzysztof Grobelny         if (!std::isfinite(*length))
609c929beaSShantappa Teekappanavar         {
61043360d0SShantappa Teekappanavar             // Cable length is NaN by default, do not throw an error
62043360d0SShantappa Teekappanavar             if (!std::isnan(*length))
6389474494SKrzysztof Grobelny             {
649c929beaSShantappa Teekappanavar                 messages::internalError(resp);
659c929beaSShantappa Teekappanavar                 return;
669c929beaSShantappa Teekappanavar             }
67043360d0SShantappa Teekappanavar         }
68043360d0SShantappa Teekappanavar         else
69043360d0SShantappa Teekappanavar         {
7089474494SKrzysztof Grobelny             resp.jsonValue["LengthMeters"] = *length;
719c929beaSShantappa Teekappanavar         }
729c929beaSShantappa Teekappanavar     }
73043360d0SShantappa Teekappanavar }
749c929beaSShantappa Teekappanavar 
759c929beaSShantappa Teekappanavar /**
769c929beaSShantappa Teekappanavar  * @brief Api to get Cable properties.
779c929beaSShantappa Teekappanavar  * @param[in,out]   asyncResp       Async HTTP response.
789c929beaSShantappa Teekappanavar  * @param[in]       cableObjectPath Object path of the Cable.
799c929beaSShantappa Teekappanavar  * @param[in]       serviceMap      A map to hold Service and corresponding
809c929beaSShantappa Teekappanavar  * interface list for the given cable id.
819c929beaSShantappa Teekappanavar  */
829c929beaSShantappa Teekappanavar inline void
839c929beaSShantappa Teekappanavar     getCableProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
849c929beaSShantappa Teekappanavar                        const std::string& cableObjectPath,
859c929beaSShantappa Teekappanavar                        const dbus::utility::MapperServiceMap& serviceMap)
869c929beaSShantappa Teekappanavar {
8762598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get Properties for cable {}", cableObjectPath);
889c929beaSShantappa Teekappanavar 
899c929beaSShantappa Teekappanavar     for (const auto& [service, interfaces] : serviceMap)
909c929beaSShantappa Teekappanavar     {
919c929beaSShantappa Teekappanavar         for (const auto& interface : interfaces)
929c929beaSShantappa Teekappanavar         {
930c2ba59dSAkshit Shah             if (interface == "xyz.openbmc_project.Inventory.Item.Cable")
949c929beaSShantappa Teekappanavar             {
9589474494SKrzysztof Grobelny                 sdbusplus::asio::getAllProperties(
9689474494SKrzysztof Grobelny                     *crow::connections::systemBus, service, cableObjectPath,
9789474494SKrzysztof Grobelny                     interface,
989c929beaSShantappa Teekappanavar                     [asyncResp](
995e7e2dc5SEd Tanous                         const boost::system::error_code& ec,
1009c929beaSShantappa Teekappanavar                         const dbus::utility::DBusPropertiesMap& properties) {
1019c929beaSShantappa Teekappanavar                     fillCableProperties(asyncResp->res, ec, properties);
10289474494SKrzysztof Grobelny                 });
1039c929beaSShantappa Teekappanavar             }
1040c2ba59dSAkshit Shah             else if (interface == "xyz.openbmc_project.Inventory.Item")
1050c2ba59dSAkshit Shah             {
1060c2ba59dSAkshit Shah                 sdbusplus::asio::getProperty<bool>(
1070c2ba59dSAkshit Shah                     *crow::connections::systemBus, service, cableObjectPath,
1080c2ba59dSAkshit Shah                     interface, "Present",
1090c2ba59dSAkshit Shah                     [asyncResp, cableObjectPath](
1100c2ba59dSAkshit Shah                         const boost::system::error_code& ec, bool present) {
1110c2ba59dSAkshit Shah                     if (ec)
1120c2ba59dSAkshit Shah                     {
1130c2ba59dSAkshit Shah                         BMCWEB_LOG_DEBUG(
1140c2ba59dSAkshit Shah                             "get presence failed for Cable {} with error {}",
1150c2ba59dSAkshit Shah                             cableObjectPath, ec);
1160c2ba59dSAkshit Shah                         if (ec.value() != EBADR)
1170c2ba59dSAkshit Shah                         {
1180c2ba59dSAkshit Shah                             messages::internalError(asyncResp->res);
1190c2ba59dSAkshit Shah                         }
1200c2ba59dSAkshit Shah                         return;
1210c2ba59dSAkshit Shah                     }
1220c2ba59dSAkshit Shah 
1230c2ba59dSAkshit Shah                     if (!present)
1240c2ba59dSAkshit Shah                     {
125*539d8c6bSEd Tanous                         asyncResp->res.jsonValue["Status"]["State"] =
126*539d8c6bSEd Tanous                             resource::State::Absent;
1270c2ba59dSAkshit Shah                     }
1280c2ba59dSAkshit Shah                 });
1290c2ba59dSAkshit Shah             }
1300c2ba59dSAkshit Shah         }
1319c929beaSShantappa Teekappanavar     }
1329c929beaSShantappa Teekappanavar }
1339c929beaSShantappa Teekappanavar 
1349c929beaSShantappa Teekappanavar /**
1359c929beaSShantappa Teekappanavar  * The Cable schema
1369c929beaSShantappa Teekappanavar  */
1379c929beaSShantappa Teekappanavar inline void requestRoutesCable(App& app)
1389c929beaSShantappa Teekappanavar {
1399c929beaSShantappa Teekappanavar     BMCWEB_ROUTE(app, "/redfish/v1/Cables/<str>/")
1409c929beaSShantappa Teekappanavar         .privileges(redfish::privileges::getCable)
1419c929beaSShantappa Teekappanavar         .methods(boost::beast::http::verb::get)(
14245ca1b86SEd Tanous             [&app](const crow::Request& req,
1439c929beaSShantappa Teekappanavar                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1449c929beaSShantappa Teekappanavar                    const std::string& cableId) {
1453ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
14645ca1b86SEd Tanous         {
14745ca1b86SEd Tanous             return;
14845ca1b86SEd Tanous         }
14962598e31SEd Tanous         BMCWEB_LOG_DEBUG("Cable Id: {}", cableId);
150e99073f5SGeorge Liu         constexpr std::array<std::string_view, 1> interfaces = {
151e99073f5SGeorge Liu             "xyz.openbmc_project.Inventory.Item.Cable"};
152e99073f5SGeorge Liu         dbus::utility::getSubTree(
153e99073f5SGeorge Liu             "/xyz/openbmc_project/inventory", 0, interfaces,
1549c929beaSShantappa Teekappanavar             [asyncResp,
155e99073f5SGeorge Liu              cableId](const boost::system::error_code& ec,
156002d39b4SEd Tanous                       const dbus::utility::MapperGetSubTreeResponse& subtree) {
1579c929beaSShantappa Teekappanavar             if (ec.value() == EBADR)
1589c929beaSShantappa Teekappanavar             {
159d8a5d5d8SJiaqing Zhao                 messages::resourceNotFound(asyncResp->res, "Cable", cableId);
1609c929beaSShantappa Teekappanavar                 return;
1619c929beaSShantappa Teekappanavar             }
1629c929beaSShantappa Teekappanavar 
1639c929beaSShantappa Teekappanavar             if (ec)
1649c929beaSShantappa Teekappanavar             {
16562598e31SEd Tanous                 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1669c929beaSShantappa Teekappanavar                 messages::internalError(asyncResp->res);
1679c929beaSShantappa Teekappanavar                 return;
1689c929beaSShantappa Teekappanavar             }
1699c929beaSShantappa Teekappanavar 
1709c929beaSShantappa Teekappanavar             for (const auto& [objectPath, serviceMap] : subtree)
1719c929beaSShantappa Teekappanavar             {
1729c929beaSShantappa Teekappanavar                 sdbusplus::message::object_path path(objectPath);
1739c929beaSShantappa Teekappanavar                 if (path.filename() != cableId)
1749c929beaSShantappa Teekappanavar                 {
1759c929beaSShantappa Teekappanavar                     continue;
1769c929beaSShantappa Teekappanavar                 }
1779c929beaSShantappa Teekappanavar 
178002d39b4SEd Tanous                 asyncResp->res.jsonValue["@odata.type"] = "#Cable.v1_0_0.Cable";
1799c929beaSShantappa Teekappanavar                 asyncResp->res.jsonValue["@odata.id"] =
180ef4c65b7SEd Tanous                     boost::urls::format("/redfish/v1/Cables/{}", cableId);
1819c929beaSShantappa Teekappanavar                 asyncResp->res.jsonValue["Id"] = cableId;
1829c929beaSShantappa Teekappanavar                 asyncResp->res.jsonValue["Name"] = "Cable";
183*539d8c6bSEd Tanous                 asyncResp->res.jsonValue["Status"]["State"] =
184*539d8c6bSEd Tanous                     resource::State::Enabled;
1859c929beaSShantappa Teekappanavar 
186002d39b4SEd Tanous                 getCableProperties(asyncResp, objectPath, serviceMap);
1879c929beaSShantappa Teekappanavar                 return;
1889c929beaSShantappa Teekappanavar             }
189002d39b4SEd Tanous             messages::resourceNotFound(asyncResp->res, "Cable", cableId);
190e99073f5SGeorge Liu         });
1919c929beaSShantappa Teekappanavar     });
1929c929beaSShantappa Teekappanavar }
1939c929beaSShantappa Teekappanavar 
1949c929beaSShantappa Teekappanavar /**
1959c929beaSShantappa Teekappanavar  * Collection of Cable resource instances
1969c929beaSShantappa Teekappanavar  */
1979c929beaSShantappa Teekappanavar inline void requestRoutesCableCollection(App& app)
1989c929beaSShantappa Teekappanavar {
1999c929beaSShantappa Teekappanavar     BMCWEB_ROUTE(app, "/redfish/v1/Cables/")
2009c929beaSShantappa Teekappanavar         .privileges(redfish::privileges::getCableCollection)
2019c929beaSShantappa Teekappanavar         .methods(boost::beast::http::verb::get)(
20245ca1b86SEd Tanous             [&app](const crow::Request& req,
2039c929beaSShantappa Teekappanavar                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
2043ba00073SCarson Labrado         if (!redfish::setUpRedfishRoute(app, req, asyncResp))
20545ca1b86SEd Tanous         {
20645ca1b86SEd Tanous             return;
20745ca1b86SEd Tanous         }
2089c929beaSShantappa Teekappanavar         asyncResp->res.jsonValue["@odata.type"] =
2099c929beaSShantappa Teekappanavar             "#CableCollection.CableCollection";
2109c929beaSShantappa Teekappanavar         asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Cables";
2119c929beaSShantappa Teekappanavar         asyncResp->res.jsonValue["Name"] = "Cable Collection";
212002d39b4SEd Tanous         asyncResp->res.jsonValue["Description"] = "Collection of Cable Entries";
2137a1dbc48SGeorge Liu         constexpr std::array<std::string_view, 1> interfaces{
2147a1dbc48SGeorge Liu             "xyz.openbmc_project.Inventory.Item.Cable"};
2159c929beaSShantappa Teekappanavar         collection_util::getCollectionMembers(
21636b5f1edSLakshmi Yadlapati             asyncResp, boost::urls::url("/redfish/v1/Cables"), interfaces,
21736b5f1edSLakshmi Yadlapati             "/xyz/openbmc_project/inventory");
2189c929beaSShantappa Teekappanavar     });
2199c929beaSShantappa Teekappanavar }
2209c929beaSShantappa Teekappanavar 
2219c929beaSShantappa Teekappanavar } // namespace redfish
222