blob: 41a5588d4c94beefdeb33d140632083864d16ae6 [file] [log] [blame]
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -06001#pragma once
George Liu7a1dbc42022-12-07 16:03:22 +08002
3#include "dbus_utility.hpp"
Ed Tanous539d8c62024-06-19 14:38:27 -07004#include "generated/enums/resource.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -08005#include "query.hpp"
6#include "registries/privilege_registry.hpp"
7#include "utils/collection.hpp"
8#include "utils/dbus_utils.hpp"
9#include "utils/json_utils.hpp"
George Liu7a1dbc42022-12-07 16:03:22 +080010
George Liue99073f2022-12-09 11:06:16 +080011#include <boost/system/error_code.hpp>
Ed Tanousef4c65b2023-04-24 15:28:50 -070012#include <boost/url/format.hpp>
Krzysztof Grobelny89474492022-09-06 16:30:38 +020013#include <sdbusplus/asio/property.hpp>
14#include <sdbusplus/unpack_properties.hpp>
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060015
George Liu7a1dbc42022-12-07 16:03:22 +080016#include <array>
17#include <string_view>
18
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060019namespace redfish
20{
21/**
22 * @brief Fill cable specific properties.
23 * @param[in,out] resp HTTP response.
24 * @param[in] ec Error code corresponding to Async method call.
25 * @param[in] properties List of Cable Properties key/value pairs.
26 */
27inline void
28 fillCableProperties(crow::Response& resp,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -080029 const boost::system::error_code& ec,
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060030 const dbus::utility::DBusPropertiesMap& properties)
31{
32 if (ec)
33 {
Gunnar Millsf933a6a2024-03-28 21:55:01 -050034 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060035 messages::internalError(resp);
36 return;
37 }
38
Krzysztof Grobelny89474492022-09-06 16:30:38 +020039 const std::string* cableTypeDescription = nullptr;
40 const double* length = nullptr;
41
42 const bool success = sdbusplus::unpackPropertiesNoThrow(
43 dbus_utils::UnpackErrorPrinter(), properties, "CableTypeDescription",
44 cableTypeDescription, "Length", length);
45
46 if (!success)
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060047 {
Krzysztof Grobelny89474492022-09-06 16:30:38 +020048 messages::internalError(resp);
49 return;
50 }
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060051
Krzysztof Grobelny89474492022-09-06 16:30:38 +020052 if (cableTypeDescription != nullptr)
53 {
54 resp.jsonValue["CableType"] = *cableTypeDescription;
55 }
56
57 if (length != nullptr)
58 {
59 if (!std::isfinite(*length))
60 {
Shantappa Teekappanavar043360d2022-11-03 13:37:24 -050061 // Cable length is NaN by default, do not throw an error
62 if (!std::isnan(*length))
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060063 {
Shantappa Teekappanavar043360d2022-11-03 13:37:24 -050064 messages::internalError(resp);
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060065 return;
66 }
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060067 }
Shantappa Teekappanavar043360d2022-11-03 13:37:24 -050068 else
69 {
70 resp.jsonValue["LengthMeters"] = *length;
71 }
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060072 }
73}
74
75/**
76 * @brief Api to get Cable properties.
77 * @param[in,out] asyncResp Async HTTP response.
78 * @param[in] cableObjectPath Object path of the Cable.
79 * @param[in] serviceMap A map to hold Service and corresponding
80 * interface list for the given cable id.
81 */
82inline void
83 getCableProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
84 const std::string& cableObjectPath,
85 const dbus::utility::MapperServiceMap& serviceMap)
86{
Ed Tanous62598e32023-07-17 17:06:25 -070087 BMCWEB_LOG_DEBUG("Get Properties for cable {}", cableObjectPath);
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060088
89 for (const auto& [service, interfaces] : serviceMap)
90 {
91 for (const auto& interface : interfaces)
92 {
Akshit Shah0c2ba592023-01-24 01:03:26 +000093 if (interface == "xyz.openbmc_project.Inventory.Item.Cable")
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060094 {
Akshit Shah0c2ba592023-01-24 01:03:26 +000095 sdbusplus::asio::getAllProperties(
96 *crow::connections::systemBus, service, cableObjectPath,
97 interface,
98 [asyncResp](
99 const boost::system::error_code& ec,
100 const dbus::utility::DBusPropertiesMap& properties) {
101 fillCableProperties(asyncResp->res, ec, properties);
Patrick Williams5a39f772023-10-20 11:20:21 -0500102 });
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -0600103 }
Akshit Shah0c2ba592023-01-24 01:03:26 +0000104 else if (interface == "xyz.openbmc_project.Inventory.Item")
105 {
106 sdbusplus::asio::getProperty<bool>(
107 *crow::connections::systemBus, service, cableObjectPath,
108 interface, "Present",
109 [asyncResp, cableObjectPath](
110 const boost::system::error_code& ec, bool present) {
111 if (ec)
112 {
113 BMCWEB_LOG_DEBUG(
114 "get presence failed for Cable {} with error {}",
115 cableObjectPath, ec);
116 if (ec.value() != EBADR)
117 {
118 messages::internalError(asyncResp->res);
119 }
120 return;
121 }
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -0600122
Akshit Shah0c2ba592023-01-24 01:03:26 +0000123 if (!present)
124 {
Ed Tanous539d8c62024-06-19 14:38:27 -0700125 asyncResp->res.jsonValue["Status"]["State"] =
126 resource::State::Absent;
Akshit Shah0c2ba592023-01-24 01:03:26 +0000127 }
Patrick Williams5a39f772023-10-20 11:20:21 -0500128 });
Akshit Shah0c2ba592023-01-24 01:03:26 +0000129 }
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -0600130 }
131 }
132}
133
134/**
135 * The Cable schema
136 */
137inline void requestRoutesCable(App& app)
138{
139 BMCWEB_ROUTE(app, "/redfish/v1/Cables/<str>/")
140 .privileges(redfish::privileges::getCable)
141 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700142 [&app](const crow::Request& req,
143 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
144 const std::string& cableId) {
Carson Labrado3ba00072022-06-06 19:40:56 +0000145 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -0700146 {
147 return;
148 }
Ed Tanous62598e32023-07-17 17:06:25 -0700149 BMCWEB_LOG_DEBUG("Cable Id: {}", cableId);
George Liue99073f2022-12-09 11:06:16 +0800150 constexpr std::array<std::string_view, 1> interfaces = {
151 "xyz.openbmc_project.Inventory.Item.Cable"};
152 dbus::utility::getSubTree(
153 "/xyz/openbmc_project/inventory", 0, interfaces,
Ed Tanous002d39b2022-05-31 08:59:27 -0700154 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +0800155 cableId](const boost::system::error_code& ec,
Ed Tanous002d39b2022-05-31 08:59:27 -0700156 const dbus::utility::MapperGetSubTreeResponse& subtree) {
157 if (ec.value() == EBADR)
158 {
Jiaqing Zhaod8a5d5d2022-08-05 16:21:51 +0800159 messages::resourceNotFound(asyncResp->res, "Cable", cableId);
Ed Tanous002d39b2022-05-31 08:59:27 -0700160 return;
161 }
162
163 if (ec)
164 {
Ed Tanous62598e32023-07-17 17:06:25 -0700165 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -0700166 messages::internalError(asyncResp->res);
167 return;
168 }
169
170 for (const auto& [objectPath, serviceMap] : subtree)
171 {
172 sdbusplus::message::object_path path(objectPath);
173 if (path.filename() != cableId)
Ed Tanous45ca1b82022-03-25 13:07:27 -0700174 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700175 continue;
Ed Tanous45ca1b82022-03-25 13:07:27 -0700176 }
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -0600177
Ed Tanous002d39b2022-05-31 08:59:27 -0700178 asyncResp->res.jsonValue["@odata.type"] = "#Cable.v1_0_0.Cable";
179 asyncResp->res.jsonValue["@odata.id"] =
Ed Tanousef4c65b2023-04-24 15:28:50 -0700180 boost::urls::format("/redfish/v1/Cables/{}", cableId);
Ed Tanous002d39b2022-05-31 08:59:27 -0700181 asyncResp->res.jsonValue["Id"] = cableId;
182 asyncResp->res.jsonValue["Name"] = "Cable";
Ed Tanous539d8c62024-06-19 14:38:27 -0700183 asyncResp->res.jsonValue["Status"]["State"] =
184 resource::State::Enabled;
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -0600185
Ed Tanous002d39b2022-05-31 08:59:27 -0700186 getCableProperties(asyncResp, objectPath, serviceMap);
187 return;
188 }
189 messages::resourceNotFound(asyncResp->res, "Cable", cableId);
Ed Tanous002d39b2022-05-31 08:59:27 -0700190 });
Patrick Williams5a39f772023-10-20 11:20:21 -0500191 });
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -0600192}
193
194/**
195 * Collection of Cable resource instances
196 */
197inline void requestRoutesCableCollection(App& app)
198{
199 BMCWEB_ROUTE(app, "/redfish/v1/Cables/")
200 .privileges(redfish::privileges::getCableCollection)
201 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700202 [&app](const crow::Request& req,
203 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Carson Labrado3ba00072022-06-06 19:40:56 +0000204 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -0700205 {
206 return;
207 }
208 asyncResp->res.jsonValue["@odata.type"] =
209 "#CableCollection.CableCollection";
210 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Cables";
211 asyncResp->res.jsonValue["Name"] = "Cable Collection";
212 asyncResp->res.jsonValue["Description"] = "Collection of Cable Entries";
George Liu7a1dbc42022-12-07 16:03:22 +0800213 constexpr std::array<std::string_view, 1> interfaces{
214 "xyz.openbmc_project.Inventory.Item.Cable"};
Ed Tanous002d39b2022-05-31 08:59:27 -0700215 collection_util::getCollectionMembers(
Lakshmi Yadlapati36b5f1e2023-09-26 23:53:28 -0500216 asyncResp, boost::urls::url("/redfish/v1/Cables"), interfaces,
217 "/xyz/openbmc_project/inventory");
Patrick Williams5a39f772023-10-20 11:20:21 -0500218 });
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -0600219}
220
221} // namespace redfish