blob: e724118eccc98a8d4fb5d19496f1b15c50e3b146 [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 Tanous3ccb3ad2023-01-13 17:40:03 -08004#include "query.hpp"
5#include "registries/privilege_registry.hpp"
6#include "utils/collection.hpp"
7#include "utils/dbus_utils.hpp"
8#include "utils/json_utils.hpp"
George Liu7a1dbc42022-12-07 16:03:22 +08009
Krzysztof Grobelny89474492022-09-06 16:30:38 +020010#include <sdbusplus/asio/property.hpp>
11#include <sdbusplus/unpack_properties.hpp>
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060012
George Liu7a1dbc42022-12-07 16:03:22 +080013#include <array>
14#include <string_view>
15
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060016namespace redfish
17{
18/**
19 * @brief Fill cable specific properties.
20 * @param[in,out] resp HTTP response.
21 * @param[in] ec Error code corresponding to Async method call.
22 * @param[in] properties List of Cable Properties key/value pairs.
23 */
24inline void
25 fillCableProperties(crow::Response& resp,
26 const boost::system::error_code ec,
27 const dbus::utility::DBusPropertiesMap& properties)
28{
29 if (ec)
30 {
31 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
32 messages::internalError(resp);
33 return;
34 }
35
Krzysztof Grobelny89474492022-09-06 16:30:38 +020036 const std::string* cableTypeDescription = nullptr;
37 const double* length = nullptr;
38
39 const bool success = sdbusplus::unpackPropertiesNoThrow(
40 dbus_utils::UnpackErrorPrinter(), properties, "CableTypeDescription",
41 cableTypeDescription, "Length", length);
42
43 if (!success)
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060044 {
Krzysztof Grobelny89474492022-09-06 16:30:38 +020045 messages::internalError(resp);
46 return;
47 }
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060048
Krzysztof Grobelny89474492022-09-06 16:30:38 +020049 if (cableTypeDescription != nullptr)
50 {
51 resp.jsonValue["CableType"] = *cableTypeDescription;
52 }
53
54 if (length != nullptr)
55 {
56 if (!std::isfinite(*length))
57 {
Shantappa Teekappanavar043360d2022-11-03 13:37:24 -050058 // Cable length is NaN by default, do not throw an error
59 if (!std::isnan(*length))
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060060 {
Shantappa Teekappanavar043360d2022-11-03 13:37:24 -050061 messages::internalError(resp);
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060062 return;
63 }
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060064 }
Shantappa Teekappanavar043360d2022-11-03 13:37:24 -050065 else
66 {
67 resp.jsonValue["LengthMeters"] = *length;
68 }
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060069 }
70}
71
72/**
73 * @brief Api to get Cable properties.
74 * @param[in,out] asyncResp Async HTTP response.
75 * @param[in] cableObjectPath Object path of the Cable.
76 * @param[in] serviceMap A map to hold Service and corresponding
77 * interface list for the given cable id.
78 */
79inline void
80 getCableProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
81 const std::string& cableObjectPath,
82 const dbus::utility::MapperServiceMap& serviceMap)
83{
84 BMCWEB_LOG_DEBUG << "Get Properties for cable " << cableObjectPath;
85
86 for (const auto& [service, interfaces] : serviceMap)
87 {
88 for (const auto& interface : interfaces)
89 {
90 if (interface != "xyz.openbmc_project.Inventory.Item.Cable")
91 {
92 continue;
93 }
94
Krzysztof Grobelny89474492022-09-06 16:30:38 +020095 sdbusplus::asio::getAllProperties(
96 *crow::connections::systemBus, service, cableObjectPath,
97 interface,
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060098 [asyncResp](
99 const boost::system::error_code ec,
100 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700101 fillCableProperties(asyncResp->res, ec, properties);
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200102 });
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -0600103 }
104 }
105}
106
107/**
108 * The Cable schema
109 */
110inline void requestRoutesCable(App& app)
111{
112 BMCWEB_ROUTE(app, "/redfish/v1/Cables/<str>/")
113 .privileges(redfish::privileges::getCable)
114 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700115 [&app](const crow::Request& req,
116 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
117 const std::string& cableId) {
Carson Labrado3ba00072022-06-06 19:40:56 +0000118 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -0700119 {
120 return;
121 }
122 BMCWEB_LOG_DEBUG << "Cable Id: " << cableId;
123 auto respHandler =
124 [asyncResp,
125 cableId](const boost::system::error_code ec,
126 const dbus::utility::MapperGetSubTreeResponse& subtree) {
127 if (ec.value() == EBADR)
128 {
Jiaqing Zhaod8a5d5d2022-08-05 16:21:51 +0800129 messages::resourceNotFound(asyncResp->res, "Cable", cableId);
Ed Tanous002d39b2022-05-31 08:59:27 -0700130 return;
131 }
132
133 if (ec)
134 {
135 BMCWEB_LOG_ERROR << "DBUS response error " << ec;
136 messages::internalError(asyncResp->res);
137 return;
138 }
139
140 for (const auto& [objectPath, serviceMap] : subtree)
141 {
142 sdbusplus::message::object_path path(objectPath);
143 if (path.filename() != cableId)
Ed Tanous45ca1b82022-03-25 13:07:27 -0700144 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700145 continue;
Ed Tanous45ca1b82022-03-25 13:07:27 -0700146 }
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -0600147
Ed Tanous002d39b2022-05-31 08:59:27 -0700148 asyncResp->res.jsonValue["@odata.type"] = "#Cable.v1_0_0.Cable";
149 asyncResp->res.jsonValue["@odata.id"] =
150 "/redfish/v1/Cables/" + cableId;
151 asyncResp->res.jsonValue["Id"] = cableId;
152 asyncResp->res.jsonValue["Name"] = "Cable";
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -0600153
Ed Tanous002d39b2022-05-31 08:59:27 -0700154 getCableProperties(asyncResp, objectPath, serviceMap);
155 return;
156 }
157 messages::resourceNotFound(asyncResp->res, "Cable", cableId);
158 };
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -0600159
Ed Tanous002d39b2022-05-31 08:59:27 -0700160 crow::connections::systemBus->async_method_call(
161 respHandler, "xyz.openbmc_project.ObjectMapper",
162 "/xyz/openbmc_project/object_mapper",
163 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
164 "/xyz/openbmc_project/inventory", 0,
165 std::array<const char*, 1>{
166 "xyz.openbmc_project.Inventory.Item.Cable"});
167 });
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -0600168}
169
170/**
171 * Collection of Cable resource instances
172 */
173inline void requestRoutesCableCollection(App& app)
174{
175 BMCWEB_ROUTE(app, "/redfish/v1/Cables/")
176 .privileges(redfish::privileges::getCableCollection)
177 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700178 [&app](const crow::Request& req,
179 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Carson Labrado3ba00072022-06-06 19:40:56 +0000180 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -0700181 {
182 return;
183 }
184 asyncResp->res.jsonValue["@odata.type"] =
185 "#CableCollection.CableCollection";
186 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Cables";
187 asyncResp->res.jsonValue["Name"] = "Cable Collection";
188 asyncResp->res.jsonValue["Description"] = "Collection of Cable Entries";
George Liu7a1dbc42022-12-07 16:03:22 +0800189 constexpr std::array<std::string_view, 1> interfaces{
190 "xyz.openbmc_project.Inventory.Item.Cable"};
Ed Tanous002d39b2022-05-31 08:59:27 -0700191 collection_util::getCollectionMembers(
George Liu7a1dbc42022-12-07 16:03:22 +0800192 asyncResp, boost::urls::url("/redfish/v1/Cables"), interfaces);
Ed Tanous002d39b2022-05-31 08:59:27 -0700193 });
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -0600194}
195
196} // namespace redfish