19c929beaSShantappa Teekappanavar #pragma once 27a1dbc48SGeorge Liu 37a1dbc48SGeorge Liu #include "dbus_utility.hpp" 43ccb3adbSEd Tanous #include "query.hpp" 53ccb3adbSEd Tanous #include "registries/privilege_registry.hpp" 63ccb3adbSEd Tanous #include "utils/collection.hpp" 73ccb3adbSEd Tanous #include "utils/dbus_utils.hpp" 83ccb3adbSEd Tanous #include "utils/json_utils.hpp" 97a1dbc48SGeorge Liu 10*e99073f5SGeorge Liu #include <boost/system/error_code.hpp> 1189474494SKrzysztof Grobelny #include <sdbusplus/asio/property.hpp> 1289474494SKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp> 139c929beaSShantappa Teekappanavar 147a1dbc48SGeorge Liu #include <array> 157a1dbc48SGeorge Liu #include <string_view> 167a1dbc48SGeorge Liu 179c929beaSShantappa Teekappanavar namespace redfish 189c929beaSShantappa Teekappanavar { 199c929beaSShantappa Teekappanavar /** 209c929beaSShantappa Teekappanavar * @brief Fill cable specific properties. 219c929beaSShantappa Teekappanavar * @param[in,out] resp HTTP response. 229c929beaSShantappa Teekappanavar * @param[in] ec Error code corresponding to Async method call. 239c929beaSShantappa Teekappanavar * @param[in] properties List of Cable Properties key/value pairs. 249c929beaSShantappa Teekappanavar */ 259c929beaSShantappa Teekappanavar inline void 269c929beaSShantappa Teekappanavar fillCableProperties(crow::Response& resp, 279c929beaSShantappa Teekappanavar const boost::system::error_code ec, 289c929beaSShantappa Teekappanavar const dbus::utility::DBusPropertiesMap& properties) 299c929beaSShantappa Teekappanavar { 309c929beaSShantappa Teekappanavar if (ec) 319c929beaSShantappa Teekappanavar { 329c929beaSShantappa Teekappanavar BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 339c929beaSShantappa Teekappanavar messages::internalError(resp); 349c929beaSShantappa Teekappanavar return; 359c929beaSShantappa Teekappanavar } 369c929beaSShantappa Teekappanavar 3789474494SKrzysztof Grobelny const std::string* cableTypeDescription = nullptr; 3889474494SKrzysztof Grobelny const double* length = nullptr; 3989474494SKrzysztof Grobelny 4089474494SKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 4189474494SKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "CableTypeDescription", 4289474494SKrzysztof Grobelny cableTypeDescription, "Length", length); 4389474494SKrzysztof Grobelny 4489474494SKrzysztof Grobelny if (!success) 459c929beaSShantappa Teekappanavar { 469c929beaSShantappa Teekappanavar messages::internalError(resp); 479c929beaSShantappa Teekappanavar return; 489c929beaSShantappa Teekappanavar } 4989474494SKrzysztof Grobelny 5089474494SKrzysztof Grobelny if (cableTypeDescription != nullptr) 5189474494SKrzysztof Grobelny { 529c929beaSShantappa Teekappanavar resp.jsonValue["CableType"] = *cableTypeDescription; 539c929beaSShantappa Teekappanavar } 549c929beaSShantappa Teekappanavar 5589474494SKrzysztof Grobelny if (length != nullptr) 569c929beaSShantappa Teekappanavar { 5789474494SKrzysztof Grobelny if (!std::isfinite(*length)) 589c929beaSShantappa Teekappanavar { 59043360d0SShantappa Teekappanavar // Cable length is NaN by default, do not throw an error 60043360d0SShantappa Teekappanavar if (!std::isnan(*length)) 6189474494SKrzysztof Grobelny { 629c929beaSShantappa Teekappanavar messages::internalError(resp); 639c929beaSShantappa Teekappanavar return; 649c929beaSShantappa Teekappanavar } 65043360d0SShantappa Teekappanavar } 66043360d0SShantappa Teekappanavar else 67043360d0SShantappa Teekappanavar { 6889474494SKrzysztof Grobelny resp.jsonValue["LengthMeters"] = *length; 699c929beaSShantappa Teekappanavar } 709c929beaSShantappa Teekappanavar } 71043360d0SShantappa Teekappanavar } 729c929beaSShantappa Teekappanavar 739c929beaSShantappa Teekappanavar /** 749c929beaSShantappa Teekappanavar * @brief Api to get Cable properties. 759c929beaSShantappa Teekappanavar * @param[in,out] asyncResp Async HTTP response. 769c929beaSShantappa Teekappanavar * @param[in] cableObjectPath Object path of the Cable. 779c929beaSShantappa Teekappanavar * @param[in] serviceMap A map to hold Service and corresponding 789c929beaSShantappa Teekappanavar * interface list for the given cable id. 799c929beaSShantappa Teekappanavar */ 809c929beaSShantappa Teekappanavar inline void 819c929beaSShantappa Teekappanavar getCableProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 829c929beaSShantappa Teekappanavar const std::string& cableObjectPath, 839c929beaSShantappa Teekappanavar const dbus::utility::MapperServiceMap& serviceMap) 849c929beaSShantappa Teekappanavar { 859c929beaSShantappa Teekappanavar BMCWEB_LOG_DEBUG << "Get Properties for cable " << cableObjectPath; 869c929beaSShantappa Teekappanavar 879c929beaSShantappa Teekappanavar for (const auto& [service, interfaces] : serviceMap) 889c929beaSShantappa Teekappanavar { 899c929beaSShantappa Teekappanavar for (const auto& interface : interfaces) 909c929beaSShantappa Teekappanavar { 919c929beaSShantappa Teekappanavar if (interface != "xyz.openbmc_project.Inventory.Item.Cable") 929c929beaSShantappa Teekappanavar { 939c929beaSShantappa Teekappanavar continue; 949c929beaSShantappa Teekappanavar } 959c929beaSShantappa Teekappanavar 9689474494SKrzysztof Grobelny sdbusplus::asio::getAllProperties( 9789474494SKrzysztof Grobelny *crow::connections::systemBus, service, cableObjectPath, 9889474494SKrzysztof Grobelny interface, 999c929beaSShantappa Teekappanavar [asyncResp]( 1009c929beaSShantappa Teekappanavar const boost::system::error_code ec, 1019c929beaSShantappa Teekappanavar const dbus::utility::DBusPropertiesMap& properties) { 1029c929beaSShantappa Teekappanavar fillCableProperties(asyncResp->res, ec, properties); 10389474494SKrzysztof Grobelny }); 1049c929beaSShantappa Teekappanavar } 1059c929beaSShantappa Teekappanavar } 1069c929beaSShantappa Teekappanavar } 1079c929beaSShantappa Teekappanavar 1089c929beaSShantappa Teekappanavar /** 1099c929beaSShantappa Teekappanavar * The Cable schema 1109c929beaSShantappa Teekappanavar */ 1119c929beaSShantappa Teekappanavar inline void requestRoutesCable(App& app) 1129c929beaSShantappa Teekappanavar { 1139c929beaSShantappa Teekappanavar BMCWEB_ROUTE(app, "/redfish/v1/Cables/<str>/") 1149c929beaSShantappa Teekappanavar .privileges(redfish::privileges::getCable) 1159c929beaSShantappa Teekappanavar .methods(boost::beast::http::verb::get)( 11645ca1b86SEd Tanous [&app](const crow::Request& req, 1179c929beaSShantappa Teekappanavar const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1189c929beaSShantappa Teekappanavar const std::string& cableId) { 1193ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 12045ca1b86SEd Tanous { 12145ca1b86SEd Tanous return; 12245ca1b86SEd Tanous } 1239c929beaSShantappa Teekappanavar BMCWEB_LOG_DEBUG << "Cable Id: " << cableId; 124*e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 125*e99073f5SGeorge Liu "xyz.openbmc_project.Inventory.Item.Cable"}; 126*e99073f5SGeorge Liu dbus::utility::getSubTree( 127*e99073f5SGeorge Liu "/xyz/openbmc_project/inventory", 0, interfaces, 1289c929beaSShantappa Teekappanavar [asyncResp, 129*e99073f5SGeorge Liu cableId](const boost::system::error_code& ec, 130002d39b4SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 1319c929beaSShantappa Teekappanavar if (ec.value() == EBADR) 1329c929beaSShantappa Teekappanavar { 133d8a5d5d8SJiaqing Zhao messages::resourceNotFound(asyncResp->res, "Cable", cableId); 1349c929beaSShantappa Teekappanavar return; 1359c929beaSShantappa Teekappanavar } 1369c929beaSShantappa Teekappanavar 1379c929beaSShantappa Teekappanavar if (ec) 1389c929beaSShantappa Teekappanavar { 1399c929beaSShantappa Teekappanavar BMCWEB_LOG_ERROR << "DBUS response error " << ec; 1409c929beaSShantappa Teekappanavar messages::internalError(asyncResp->res); 1419c929beaSShantappa Teekappanavar return; 1429c929beaSShantappa Teekappanavar } 1439c929beaSShantappa Teekappanavar 1449c929beaSShantappa Teekappanavar for (const auto& [objectPath, serviceMap] : subtree) 1459c929beaSShantappa Teekappanavar { 1469c929beaSShantappa Teekappanavar sdbusplus::message::object_path path(objectPath); 1479c929beaSShantappa Teekappanavar if (path.filename() != cableId) 1489c929beaSShantappa Teekappanavar { 1499c929beaSShantappa Teekappanavar continue; 1509c929beaSShantappa Teekappanavar } 1519c929beaSShantappa Teekappanavar 152002d39b4SEd Tanous asyncResp->res.jsonValue["@odata.type"] = "#Cable.v1_0_0.Cable"; 1539c929beaSShantappa Teekappanavar asyncResp->res.jsonValue["@odata.id"] = 1549c929beaSShantappa Teekappanavar "/redfish/v1/Cables/" + cableId; 1559c929beaSShantappa Teekappanavar asyncResp->res.jsonValue["Id"] = cableId; 1569c929beaSShantappa Teekappanavar asyncResp->res.jsonValue["Name"] = "Cable"; 1579c929beaSShantappa Teekappanavar 158002d39b4SEd Tanous getCableProperties(asyncResp, objectPath, serviceMap); 1599c929beaSShantappa Teekappanavar return; 1609c929beaSShantappa Teekappanavar } 161002d39b4SEd Tanous messages::resourceNotFound(asyncResp->res, "Cable", cableId); 162*e99073f5SGeorge Liu }); 1639c929beaSShantappa Teekappanavar }); 1649c929beaSShantappa Teekappanavar } 1659c929beaSShantappa Teekappanavar 1669c929beaSShantappa Teekappanavar /** 1679c929beaSShantappa Teekappanavar * Collection of Cable resource instances 1689c929beaSShantappa Teekappanavar */ 1699c929beaSShantappa Teekappanavar inline void requestRoutesCableCollection(App& app) 1709c929beaSShantappa Teekappanavar { 1719c929beaSShantappa Teekappanavar BMCWEB_ROUTE(app, "/redfish/v1/Cables/") 1729c929beaSShantappa Teekappanavar .privileges(redfish::privileges::getCableCollection) 1739c929beaSShantappa Teekappanavar .methods(boost::beast::http::verb::get)( 17445ca1b86SEd Tanous [&app](const crow::Request& req, 1759c929beaSShantappa Teekappanavar const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 1763ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 17745ca1b86SEd Tanous { 17845ca1b86SEd Tanous return; 17945ca1b86SEd Tanous } 1809c929beaSShantappa Teekappanavar asyncResp->res.jsonValue["@odata.type"] = 1819c929beaSShantappa Teekappanavar "#CableCollection.CableCollection"; 1829c929beaSShantappa Teekappanavar asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Cables"; 1839c929beaSShantappa Teekappanavar asyncResp->res.jsonValue["Name"] = "Cable Collection"; 184002d39b4SEd Tanous asyncResp->res.jsonValue["Description"] = "Collection of Cable Entries"; 1857a1dbc48SGeorge Liu constexpr std::array<std::string_view, 1> interfaces{ 1867a1dbc48SGeorge Liu "xyz.openbmc_project.Inventory.Item.Cable"}; 1879c929beaSShantappa Teekappanavar collection_util::getCollectionMembers( 1887a1dbc48SGeorge Liu asyncResp, boost::urls::url("/redfish/v1/Cables"), interfaces); 1899c929beaSShantappa Teekappanavar }); 1909c929beaSShantappa Teekappanavar } 1919c929beaSShantappa Teekappanavar 1929c929beaSShantappa Teekappanavar } // namespace redfish 193