blob: bc73267101ff26614bc74efe0df5298c40880848 [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
George Liue99073f2022-12-09 11:06:16 +080010#include <boost/system/error_code.hpp>
Ed Tanousef4c65b2023-04-24 15:28:50 -070011#include <boost/url/format.hpp>
Krzysztof Grobelny89474492022-09-06 16:30:38 +020012#include <sdbusplus/asio/property.hpp>
13#include <sdbusplus/unpack_properties.hpp>
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060014
George Liu7a1dbc42022-12-07 16:03:22 +080015#include <array>
16#include <string_view>
17
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060018namespace redfish
19{
20/**
21 * @brief Fill cable specific properties.
22 * @param[in,out] resp HTTP response.
23 * @param[in] ec Error code corresponding to Async method call.
24 * @param[in] properties List of Cable Properties key/value pairs.
25 */
26inline void
27 fillCableProperties(crow::Response& resp,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -080028 const boost::system::error_code& ec,
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060029 const dbus::utility::DBusPropertiesMap& properties)
30{
31 if (ec)
32 {
Gunnar Millsf933a6a2024-03-28 21:55:01 -050033 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060034 messages::internalError(resp);
35 return;
36 }
37
Krzysztof Grobelny89474492022-09-06 16:30:38 +020038 const std::string* cableTypeDescription = nullptr;
39 const double* length = nullptr;
40
41 const bool success = sdbusplus::unpackPropertiesNoThrow(
42 dbus_utils::UnpackErrorPrinter(), properties, "CableTypeDescription",
43 cableTypeDescription, "Length", length);
44
45 if (!success)
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060046 {
Krzysztof Grobelny89474492022-09-06 16:30:38 +020047 messages::internalError(resp);
48 return;
49 }
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060050
Krzysztof Grobelny89474492022-09-06 16:30:38 +020051 if (cableTypeDescription != nullptr)
52 {
53 resp.jsonValue["CableType"] = *cableTypeDescription;
54 }
55
56 if (length != nullptr)
57 {
58 if (!std::isfinite(*length))
59 {
Shantappa Teekappanavar043360d2022-11-03 13:37:24 -050060 // Cable length is NaN by default, do not throw an error
61 if (!std::isnan(*length))
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060062 {
Shantappa Teekappanavar043360d2022-11-03 13:37:24 -050063 messages::internalError(resp);
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060064 return;
65 }
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060066 }
Shantappa Teekappanavar043360d2022-11-03 13:37:24 -050067 else
68 {
69 resp.jsonValue["LengthMeters"] = *length;
70 }
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060071 }
72}
73
74/**
75 * @brief Api to get Cable properties.
76 * @param[in,out] asyncResp Async HTTP response.
77 * @param[in] cableObjectPath Object path of the Cable.
78 * @param[in] serviceMap A map to hold Service and corresponding
79 * interface list for the given cable id.
80 */
81inline void
82 getCableProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
83 const std::string& cableObjectPath,
84 const dbus::utility::MapperServiceMap& serviceMap)
85{
Ed Tanous62598e32023-07-17 17:06:25 -070086 BMCWEB_LOG_DEBUG("Get Properties for cable {}", cableObjectPath);
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060087
88 for (const auto& [service, interfaces] : serviceMap)
89 {
90 for (const auto& interface : interfaces)
91 {
Akshit Shah0c2ba592023-01-24 01:03:26 +000092 if (interface == "xyz.openbmc_project.Inventory.Item.Cable")
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -060093 {
Akshit Shah0c2ba592023-01-24 01:03:26 +000094 sdbusplus::asio::getAllProperties(
95 *crow::connections::systemBus, service, cableObjectPath,
96 interface,
97 [asyncResp](
98 const boost::system::error_code& ec,
99 const dbus::utility::DBusPropertiesMap& properties) {
100 fillCableProperties(asyncResp->res, ec, properties);
Patrick Williams5a39f772023-10-20 11:20:21 -0500101 });
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -0600102 }
Akshit Shah0c2ba592023-01-24 01:03:26 +0000103 else if (interface == "xyz.openbmc_project.Inventory.Item")
104 {
105 sdbusplus::asio::getProperty<bool>(
106 *crow::connections::systemBus, service, cableObjectPath,
107 interface, "Present",
108 [asyncResp, cableObjectPath](
109 const boost::system::error_code& ec, bool present) {
110 if (ec)
111 {
112 BMCWEB_LOG_DEBUG(
113 "get presence failed for Cable {} with error {}",
114 cableObjectPath, ec);
115 if (ec.value() != EBADR)
116 {
117 messages::internalError(asyncResp->res);
118 }
119 return;
120 }
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -0600121
Akshit Shah0c2ba592023-01-24 01:03:26 +0000122 if (!present)
123 {
124 asyncResp->res.jsonValue["Status"]["State"] = "Absent";
125 }
Patrick Williams5a39f772023-10-20 11:20:21 -0500126 });
Akshit Shah0c2ba592023-01-24 01:03:26 +0000127 }
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -0600128 }
129 }
130}
131
132/**
133 * The Cable schema
134 */
135inline void requestRoutesCable(App& app)
136{
137 BMCWEB_ROUTE(app, "/redfish/v1/Cables/<str>/")
138 .privileges(redfish::privileges::getCable)
139 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700140 [&app](const crow::Request& req,
141 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
142 const std::string& cableId) {
Carson Labrado3ba00072022-06-06 19:40:56 +0000143 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -0700144 {
145 return;
146 }
Ed Tanous62598e32023-07-17 17:06:25 -0700147 BMCWEB_LOG_DEBUG("Cable Id: {}", cableId);
George Liue99073f2022-12-09 11:06:16 +0800148 constexpr std::array<std::string_view, 1> interfaces = {
149 "xyz.openbmc_project.Inventory.Item.Cable"};
150 dbus::utility::getSubTree(
151 "/xyz/openbmc_project/inventory", 0, interfaces,
Ed Tanous002d39b2022-05-31 08:59:27 -0700152 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +0800153 cableId](const boost::system::error_code& ec,
Ed Tanous002d39b2022-05-31 08:59:27 -0700154 const dbus::utility::MapperGetSubTreeResponse& subtree) {
155 if (ec.value() == EBADR)
156 {
Jiaqing Zhaod8a5d5d2022-08-05 16:21:51 +0800157 messages::resourceNotFound(asyncResp->res, "Cable", cableId);
Ed Tanous002d39b2022-05-31 08:59:27 -0700158 return;
159 }
160
161 if (ec)
162 {
Ed Tanous62598e32023-07-17 17:06:25 -0700163 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -0700164 messages::internalError(asyncResp->res);
165 return;
166 }
167
168 for (const auto& [objectPath, serviceMap] : subtree)
169 {
170 sdbusplus::message::object_path path(objectPath);
171 if (path.filename() != cableId)
Ed Tanous45ca1b82022-03-25 13:07:27 -0700172 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700173 continue;
Ed Tanous45ca1b82022-03-25 13:07:27 -0700174 }
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -0600175
Ed Tanous002d39b2022-05-31 08:59:27 -0700176 asyncResp->res.jsonValue["@odata.type"] = "#Cable.v1_0_0.Cable";
177 asyncResp->res.jsonValue["@odata.id"] =
Ed Tanousef4c65b2023-04-24 15:28:50 -0700178 boost::urls::format("/redfish/v1/Cables/{}", cableId);
Ed Tanous002d39b2022-05-31 08:59:27 -0700179 asyncResp->res.jsonValue["Id"] = cableId;
180 asyncResp->res.jsonValue["Name"] = "Cable";
Akshit Shah0c2ba592023-01-24 01:03:26 +0000181 asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -0600182
Ed Tanous002d39b2022-05-31 08:59:27 -0700183 getCableProperties(asyncResp, objectPath, serviceMap);
184 return;
185 }
186 messages::resourceNotFound(asyncResp->res, "Cable", cableId);
Ed Tanous002d39b2022-05-31 08:59:27 -0700187 });
Patrick Williams5a39f772023-10-20 11:20:21 -0500188 });
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -0600189}
190
191/**
192 * Collection of Cable resource instances
193 */
194inline void requestRoutesCableCollection(App& app)
195{
196 BMCWEB_ROUTE(app, "/redfish/v1/Cables/")
197 .privileges(redfish::privileges::getCableCollection)
198 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700199 [&app](const crow::Request& req,
200 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Carson Labrado3ba00072022-06-06 19:40:56 +0000201 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -0700202 {
203 return;
204 }
205 asyncResp->res.jsonValue["@odata.type"] =
206 "#CableCollection.CableCollection";
207 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Cables";
208 asyncResp->res.jsonValue["Name"] = "Cable Collection";
209 asyncResp->res.jsonValue["Description"] = "Collection of Cable Entries";
George Liu7a1dbc42022-12-07 16:03:22 +0800210 constexpr std::array<std::string_view, 1> interfaces{
211 "xyz.openbmc_project.Inventory.Item.Cable"};
Ed Tanous002d39b2022-05-31 08:59:27 -0700212 collection_util::getCollectionMembers(
Lakshmi Yadlapati36b5f1e2023-09-26 23:53:28 -0500213 asyncResp, boost::urls::url("/redfish/v1/Cables"), interfaces,
214 "/xyz/openbmc_project/inventory");
Patrick Williams5a39f772023-10-20 11:20:21 -0500215 });
Shantappa Teekappanavar9c929be2021-12-16 19:02:52 -0600216}
217
218} // namespace redfish