blob: 3cb8c1d3f5f4c03f922eccd89bf589588f127d0f [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"
4
Ed Tanous45ca1b82022-03-25 13:07:27 -07005#include <query.hpp>
Krzysztof Grobelny89474492022-09-06 16:30:38 +02006#include <sdbusplus/asio/property.hpp>
7#include <sdbusplus/unpack_properties.hpp>
8#include <utils/dbus_utils.hpp>
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -06009#include <utils/json_utils.hpp>
10
George Liu7a1dbc42022-12-07 16:03:22 +080011#include <array>
12#include <string_view>
13
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060014namespace redfish
15{
16/**
17 * @brief Fill cable specific properties.
18 * @param[in,out] resp HTTP response.
19 * @param[in] ec Error code corresponding to Async method call.
20 * @param[in] properties List of Cable Properties key/value pairs.
21 */
22inline void
23 fillCableProperties(crow::Response& resp,
24 const boost::system::error_code ec,
25 const dbus::utility::DBusPropertiesMap& properties)
26{
27 if (ec)
28 {
29 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
30 messages::internalError(resp);
31 return;
32 }
33
Krzysztof Grobelny89474492022-09-06 16:30:38 +020034 const std::string* cableTypeDescription = nullptr;
35 const double* length = nullptr;
36
37 const bool success = sdbusplus::unpackPropertiesNoThrow(
38 dbus_utils::UnpackErrorPrinter(), properties, "CableTypeDescription",
39 cableTypeDescription, "Length", length);
40
41 if (!success)
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060042 {
Krzysztof Grobelny89474492022-09-06 16:30:38 +020043 messages::internalError(resp);
44 return;
45 }
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060046
Krzysztof Grobelny89474492022-09-06 16:30:38 +020047 if (cableTypeDescription != nullptr)
48 {
49 resp.jsonValue["CableType"] = *cableTypeDescription;
50 }
51
52 if (length != nullptr)
53 {
54 if (!std::isfinite(*length))
55 {
Shantappa Teekappanavar043360d2022-11-03 13:37:24 -050056 // Cable length is NaN by default, do not throw an error
57 if (!std::isnan(*length))
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060058 {
Shantappa Teekappanavar043360d2022-11-03 13:37:24 -050059 messages::internalError(resp);
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060060 return;
61 }
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060062 }
Shantappa Teekappanavar043360d2022-11-03 13:37:24 -050063 else
64 {
65 resp.jsonValue["LengthMeters"] = *length;
66 }
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060067 }
68}
69
70/**
71 * @brief Api to get Cable properties.
72 * @param[in,out] asyncResp Async HTTP response.
73 * @param[in] cableObjectPath Object path of the Cable.
74 * @param[in] serviceMap A map to hold Service and corresponding
75 * interface list for the given cable id.
76 */
77inline void
78 getCableProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
79 const std::string& cableObjectPath,
80 const dbus::utility::MapperServiceMap& serviceMap)
81{
82 BMCWEB_LOG_DEBUG << "Get Properties for cable " << cableObjectPath;
83
84 for (const auto& [service, interfaces] : serviceMap)
85 {
86 for (const auto& interface : interfaces)
87 {
88 if (interface != "xyz.openbmc_project.Inventory.Item.Cable")
89 {
90 continue;
91 }
92
Krzysztof Grobelny89474492022-09-06 16:30:38 +020093 sdbusplus::asio::getAllProperties(
94 *crow::connections::systemBus, service, cableObjectPath,
95 interface,
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060096 [asyncResp](
97 const boost::system::error_code ec,
98 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -070099 fillCableProperties(asyncResp->res, ec, properties);
Krzysztof Grobelny89474492022-09-06 16:30:38 +0200100 });
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -0600101 }
102 }
103}
104
105/**
106 * The Cable schema
107 */
108inline void requestRoutesCable(App& app)
109{
110 BMCWEB_ROUTE(app, "/redfish/v1/Cables/<str>/")
111 .privileges(redfish::privileges::getCable)
112 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700113 [&app](const crow::Request& req,
114 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
115 const std::string& cableId) {
Carson Labrado3ba00072022-06-06 19:40:56 +0000116 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -0700117 {
118 return;
119 }
120 BMCWEB_LOG_DEBUG << "Cable Id: " << cableId;
121 auto respHandler =
122 [asyncResp,
123 cableId](const boost::system::error_code ec,
124 const dbus::utility::MapperGetSubTreeResponse& subtree) {
125 if (ec.value() == EBADR)
126 {
Jiaqing Zhaod8a5d5d2022-08-05 16:21:51 +0800127 messages::resourceNotFound(asyncResp->res, "Cable", cableId);
Ed Tanous002d39b2022-05-31 08:59:27 -0700128 return;
129 }
130
131 if (ec)
132 {
133 BMCWEB_LOG_ERROR << "DBUS response error " << ec;
134 messages::internalError(asyncResp->res);
135 return;
136 }
137
138 for (const auto& [objectPath, serviceMap] : subtree)
139 {
140 sdbusplus::message::object_path path(objectPath);
141 if (path.filename() != cableId)
Ed Tanous45ca1b82022-03-25 13:07:27 -0700142 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700143 continue;
Ed Tanous45ca1b82022-03-25 13:07:27 -0700144 }
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -0600145
Ed Tanous002d39b2022-05-31 08:59:27 -0700146 asyncResp->res.jsonValue["@odata.type"] = "#Cable.v1_0_0.Cable";
147 asyncResp->res.jsonValue["@odata.id"] =
148 "/redfish/v1/Cables/" + cableId;
149 asyncResp->res.jsonValue["Id"] = cableId;
150 asyncResp->res.jsonValue["Name"] = "Cable";
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -0600151
Ed Tanous002d39b2022-05-31 08:59:27 -0700152 getCableProperties(asyncResp, objectPath, serviceMap);
153 return;
154 }
155 messages::resourceNotFound(asyncResp->res, "Cable", cableId);
156 };
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -0600157
Ed Tanous002d39b2022-05-31 08:59:27 -0700158 crow::connections::systemBus->async_method_call(
159 respHandler, "xyz.openbmc_project.ObjectMapper",
160 "/xyz/openbmc_project/object_mapper",
161 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
162 "/xyz/openbmc_project/inventory", 0,
163 std::array<const char*, 1>{
164 "xyz.openbmc_project.Inventory.Item.Cable"});
165 });
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -0600166}
167
168/**
169 * Collection of Cable resource instances
170 */
171inline void requestRoutesCableCollection(App& app)
172{
173 BMCWEB_ROUTE(app, "/redfish/v1/Cables/")
174 .privileges(redfish::privileges::getCableCollection)
175 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700176 [&app](const crow::Request& req,
177 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Carson Labrado3ba00072022-06-06 19:40:56 +0000178 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -0700179 {
180 return;
181 }
182 asyncResp->res.jsonValue["@odata.type"] =
183 "#CableCollection.CableCollection";
184 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Cables";
185 asyncResp->res.jsonValue["Name"] = "Cable Collection";
186 asyncResp->res.jsonValue["Description"] = "Collection of Cable Entries";
George Liu7a1dbc42022-12-07 16:03:22 +0800187 constexpr std::array<std::string_view, 1> interfaces{
188 "xyz.openbmc_project.Inventory.Item.Cable"};
Ed Tanous002d39b2022-05-31 08:59:27 -0700189 collection_util::getCollectionMembers(
George Liu7a1dbc42022-12-07 16:03:22 +0800190 asyncResp, boost::urls::url("/redfish/v1/Cables"), interfaces);
Ed Tanous002d39b2022-05-31 08:59:27 -0700191 });
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -0600192}
193
194} // namespace redfish