1*40e9b92eSEd Tanous // SPDX-License-Identifier: Apache-2.0 2*40e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright OpenBMC Authors 39c929beaSShantappa Teekappanavar #pragma once 47a1dbc48SGeorge Liu 57a1dbc48SGeorge Liu #include "dbus_utility.hpp" 6539d8c6bSEd Tanous #include "generated/enums/resource.hpp" 73ccb3adbSEd Tanous #include "query.hpp" 83ccb3adbSEd Tanous #include "registries/privilege_registry.hpp" 93ccb3adbSEd Tanous #include "utils/collection.hpp" 103ccb3adbSEd Tanous #include "utils/dbus_utils.hpp" 113ccb3adbSEd Tanous #include "utils/json_utils.hpp" 127a1dbc48SGeorge Liu 13e99073f5SGeorge Liu #include <boost/system/error_code.hpp> 14ef4c65b7SEd Tanous #include <boost/url/format.hpp> 1589474494SKrzysztof Grobelny #include <sdbusplus/asio/property.hpp> 1689474494SKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp> 179c929beaSShantappa Teekappanavar 187a1dbc48SGeorge Liu #include <array> 197a1dbc48SGeorge Liu #include <string_view> 207a1dbc48SGeorge Liu 219c929beaSShantappa Teekappanavar namespace redfish 229c929beaSShantappa Teekappanavar { 239c929beaSShantappa Teekappanavar /** 249c929beaSShantappa Teekappanavar * @brief Fill cable specific properties. 259c929beaSShantappa Teekappanavar * @param[in,out] resp HTTP response. 269c929beaSShantappa Teekappanavar * @param[in] ec Error code corresponding to Async method call. 279c929beaSShantappa Teekappanavar * @param[in] properties List of Cable Properties key/value pairs. 289c929beaSShantappa Teekappanavar */ 29bd79bce8SPatrick Williams inline void fillCableProperties( 30bd79bce8SPatrick Williams crow::Response& resp, const boost::system::error_code& ec, 319c929beaSShantappa Teekappanavar const dbus::utility::DBusPropertiesMap& properties) 329c929beaSShantappa Teekappanavar { 339c929beaSShantappa Teekappanavar if (ec) 349c929beaSShantappa Teekappanavar { 35f933a6a0SGunnar Mills BMCWEB_LOG_ERROR("DBUS response error {}", ec); 369c929beaSShantappa Teekappanavar messages::internalError(resp); 379c929beaSShantappa Teekappanavar return; 389c929beaSShantappa Teekappanavar } 399c929beaSShantappa Teekappanavar 4089474494SKrzysztof Grobelny const std::string* cableTypeDescription = nullptr; 4189474494SKrzysztof Grobelny const double* length = nullptr; 4289474494SKrzysztof Grobelny 4389474494SKrzysztof Grobelny const bool success = sdbusplus::unpackPropertiesNoThrow( 4489474494SKrzysztof Grobelny dbus_utils::UnpackErrorPrinter(), properties, "CableTypeDescription", 4589474494SKrzysztof Grobelny cableTypeDescription, "Length", length); 4689474494SKrzysztof Grobelny 4789474494SKrzysztof Grobelny if (!success) 489c929beaSShantappa Teekappanavar { 499c929beaSShantappa Teekappanavar messages::internalError(resp); 509c929beaSShantappa Teekappanavar return; 519c929beaSShantappa Teekappanavar } 5289474494SKrzysztof Grobelny 5389474494SKrzysztof Grobelny if (cableTypeDescription != nullptr) 5489474494SKrzysztof Grobelny { 559c929beaSShantappa Teekappanavar resp.jsonValue["CableType"] = *cableTypeDescription; 569c929beaSShantappa Teekappanavar } 579c929beaSShantappa Teekappanavar 5889474494SKrzysztof Grobelny if (length != nullptr) 599c929beaSShantappa Teekappanavar { 6089474494SKrzysztof Grobelny if (!std::isfinite(*length)) 619c929beaSShantappa Teekappanavar { 62043360d0SShantappa Teekappanavar // Cable length is NaN by default, do not throw an error 63043360d0SShantappa Teekappanavar if (!std::isnan(*length)) 6489474494SKrzysztof Grobelny { 659c929beaSShantappa Teekappanavar messages::internalError(resp); 669c929beaSShantappa Teekappanavar return; 679c929beaSShantappa Teekappanavar } 68043360d0SShantappa Teekappanavar } 69043360d0SShantappa Teekappanavar else 70043360d0SShantappa Teekappanavar { 7189474494SKrzysztof Grobelny resp.jsonValue["LengthMeters"] = *length; 729c929beaSShantappa Teekappanavar } 739c929beaSShantappa Teekappanavar } 74043360d0SShantappa Teekappanavar } 759c929beaSShantappa Teekappanavar 769c929beaSShantappa Teekappanavar /** 779c929beaSShantappa Teekappanavar * @brief Api to get Cable properties. 789c929beaSShantappa Teekappanavar * @param[in,out] asyncResp Async HTTP response. 799c929beaSShantappa Teekappanavar * @param[in] cableObjectPath Object path of the Cable. 809c929beaSShantappa Teekappanavar * @param[in] serviceMap A map to hold Service and corresponding 819c929beaSShantappa Teekappanavar * interface list for the given cable id. 829c929beaSShantappa Teekappanavar */ 839c929beaSShantappa Teekappanavar inline void 849c929beaSShantappa Teekappanavar getCableProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 859c929beaSShantappa Teekappanavar const std::string& cableObjectPath, 869c929beaSShantappa Teekappanavar const dbus::utility::MapperServiceMap& serviceMap) 879c929beaSShantappa Teekappanavar { 8862598e31SEd Tanous BMCWEB_LOG_DEBUG("Get Properties for cable {}", cableObjectPath); 899c929beaSShantappa Teekappanavar 909c929beaSShantappa Teekappanavar for (const auto& [service, interfaces] : serviceMap) 919c929beaSShantappa Teekappanavar { 929c929beaSShantappa Teekappanavar for (const auto& interface : interfaces) 939c929beaSShantappa Teekappanavar { 940c2ba59dSAkshit Shah if (interface == "xyz.openbmc_project.Inventory.Item.Cable") 959c929beaSShantappa Teekappanavar { 96deae6a78SEd Tanous dbus::utility::getAllProperties( 9789474494SKrzysztof Grobelny *crow::connections::systemBus, service, cableObjectPath, 9889474494SKrzysztof Grobelny interface, 999c929beaSShantappa Teekappanavar [asyncResp]( 1005e7e2dc5SEd Tanous const boost::system::error_code& ec, 1019c929beaSShantappa Teekappanavar const dbus::utility::DBusPropertiesMap& properties) { 1029c929beaSShantappa Teekappanavar fillCableProperties(asyncResp->res, ec, properties); 10389474494SKrzysztof Grobelny }); 1049c929beaSShantappa Teekappanavar } 1050c2ba59dSAkshit Shah else if (interface == "xyz.openbmc_project.Inventory.Item") 1060c2ba59dSAkshit Shah { 107deae6a78SEd Tanous dbus::utility::getProperty<bool>( 108deae6a78SEd Tanous service, cableObjectPath, 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 { 125539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = 126539d8c6bSEd 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, 156bd79bce8SPatrick Williams const dbus::utility::MapperGetSubTreeResponse& 157bd79bce8SPatrick Williams subtree) { 1589c929beaSShantappa Teekappanavar if (ec.value() == EBADR) 1599c929beaSShantappa Teekappanavar { 160bd79bce8SPatrick Williams messages::resourceNotFound(asyncResp->res, "Cable", 161bd79bce8SPatrick Williams cableId); 1629c929beaSShantappa Teekappanavar return; 1639c929beaSShantappa Teekappanavar } 1649c929beaSShantappa Teekappanavar 1659c929beaSShantappa Teekappanavar if (ec) 1669c929beaSShantappa Teekappanavar { 16762598e31SEd Tanous BMCWEB_LOG_ERROR("DBUS response error {}", ec); 1689c929beaSShantappa Teekappanavar messages::internalError(asyncResp->res); 1699c929beaSShantappa Teekappanavar return; 1709c929beaSShantappa Teekappanavar } 1719c929beaSShantappa Teekappanavar 1729c929beaSShantappa Teekappanavar for (const auto& [objectPath, serviceMap] : subtree) 1739c929beaSShantappa Teekappanavar { 1749c929beaSShantappa Teekappanavar sdbusplus::message::object_path path(objectPath); 1759c929beaSShantappa Teekappanavar if (path.filename() != cableId) 1769c929beaSShantappa Teekappanavar { 1779c929beaSShantappa Teekappanavar continue; 1789c929beaSShantappa Teekappanavar } 1799c929beaSShantappa Teekappanavar 180bd79bce8SPatrick Williams asyncResp->res.jsonValue["@odata.type"] = 181bd79bce8SPatrick Williams "#Cable.v1_0_0.Cable"; 1829c929beaSShantappa Teekappanavar asyncResp->res.jsonValue["@odata.id"] = 183bd79bce8SPatrick Williams boost::urls::format("/redfish/v1/Cables/{}", 184bd79bce8SPatrick Williams cableId); 1859c929beaSShantappa Teekappanavar asyncResp->res.jsonValue["Id"] = cableId; 1869c929beaSShantappa Teekappanavar asyncResp->res.jsonValue["Name"] = "Cable"; 187539d8c6bSEd Tanous asyncResp->res.jsonValue["Status"]["State"] = 188539d8c6bSEd Tanous resource::State::Enabled; 1899c929beaSShantappa Teekappanavar 190bd79bce8SPatrick Williams getCableProperties(asyncResp, objectPath, 191bd79bce8SPatrick Williams serviceMap); 1929c929beaSShantappa Teekappanavar return; 1939c929beaSShantappa Teekappanavar } 194bd79bce8SPatrick Williams messages::resourceNotFound(asyncResp->res, "Cable", 195bd79bce8SPatrick Williams cableId); 196e99073f5SGeorge Liu }); 1979c929beaSShantappa Teekappanavar }); 1989c929beaSShantappa Teekappanavar } 1999c929beaSShantappa Teekappanavar 2009c929beaSShantappa Teekappanavar /** 2019c929beaSShantappa Teekappanavar * Collection of Cable resource instances 2029c929beaSShantappa Teekappanavar */ 2039c929beaSShantappa Teekappanavar inline void requestRoutesCableCollection(App& app) 2049c929beaSShantappa Teekappanavar { 2059c929beaSShantappa Teekappanavar BMCWEB_ROUTE(app, "/redfish/v1/Cables/") 2069c929beaSShantappa Teekappanavar .privileges(redfish::privileges::getCableCollection) 2079c929beaSShantappa Teekappanavar .methods(boost::beast::http::verb::get)( 20845ca1b86SEd Tanous [&app](const crow::Request& req, 2099c929beaSShantappa Teekappanavar const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { 2103ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 21145ca1b86SEd Tanous { 21245ca1b86SEd Tanous return; 21345ca1b86SEd Tanous } 2149c929beaSShantappa Teekappanavar asyncResp->res.jsonValue["@odata.type"] = 2159c929beaSShantappa Teekappanavar "#CableCollection.CableCollection"; 2169c929beaSShantappa Teekappanavar asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Cables"; 2179c929beaSShantappa Teekappanavar asyncResp->res.jsonValue["Name"] = "Cable Collection"; 218bd79bce8SPatrick Williams asyncResp->res.jsonValue["Description"] = 219bd79bce8SPatrick Williams "Collection of Cable Entries"; 2207a1dbc48SGeorge Liu constexpr std::array<std::string_view, 1> interfaces{ 2217a1dbc48SGeorge Liu "xyz.openbmc_project.Inventory.Item.Cable"}; 2229c929beaSShantappa Teekappanavar collection_util::getCollectionMembers( 223bd79bce8SPatrick Williams asyncResp, boost::urls::url("/redfish/v1/Cables"), 224bd79bce8SPatrick Williams interfaces, "/xyz/openbmc_project/inventory"); 2259c929beaSShantappa Teekappanavar }); 2269c929beaSShantappa Teekappanavar } 2279c929beaSShantappa Teekappanavar 2289c929beaSShantappa Teekappanavar } // namespace redfish 229