summaryrefslogtreecommitdiff
path: root/redfish-core
diff options
context:
space:
mode:
authorShantappa Teekappanavar <sbteeks@yahoo.com>2021-12-17 04:02:52 +0300
committerEd Tanous <ed@tanous.net>2022-01-26 21:27:54 +0300
commit9c929bea78857633f2b71b356abf4aa4b1ac56d2 (patch)
tree33c1dc9af157337eebf9589900a3406d777d4c55 /redfish-core
parent71b861b64bde714410c4fe94f1628a70cb6b17aa (diff)
downloadbmcweb-9c929bea78857633f2b71b356abf4aa4b1ac56d2.tar.xz
Implement Cable schema
This commit implements Cable and Cable collection schema on bmcweb. Testing: Validator: @odata.id /redfish/v1/Cables odata Exists PASS @odata.type #CableCollection.CableCollection odata Exists PASS Members@odata.count 2 odata Exists PASS Members Array (size: 2) links: Cable Yes ... Members[0] Link: /redfish/v1/Cables/dp0_cable0 link: Cable Yes PASS Members[1] Link: /redfish/v1/Cables/dp0_cable1 link: Cable Yes PASS Description Collection of Cable Entries none Yes PASS Name Cable Collection none Yes PASS Oem - Resource.Oem No Optional Property Name Value Type Exists Result @odata.id /redfish/v1/Cables/dp0_cable0 odata Exists PASS @odata.type #Cable.v1_0_0.Cable odata Exists PASS CableType string Yes PASS LengthMeters - number No Optional Id dp0_cable0 none Yes PASS Name Cable none Yes PASS Property Name Value Type Exists Result @odata.id /redfish/v1/Cables/dp0_cable1 odata Exists PASS @odata.type #Cable.v1_0_0.Cable odata Exists PASS CableType string Yes PASS LengthMeters - number No Optional Id dp0_cable1 none Yes PASS Name Cable none Yes PASS Note: Removed some of the fields that are optional to reduce commit msg Tesing with Curl commands: $ curl -k -X GET https://{$bmc}/redfish/v1/Cables { "@odata.id": "/redfish/v1/Cables", "@odata.type": "#CableCollection.CableCollection", "Description": "Collection of Cable Entries", "Members": [ { "@odata.id": "/redfish/v1/Cables/dp0_cable0" }, { "@odata.id": "/redfish/v1/Cables/dp0_cable1" } ], "Members@odata.count": 2, "Name": "Cable Collection" } $ curl -k -X GET https://{$bmc}/redfish/v1/Cables/dp0_cable0 { "@odata.id": "/redfish/v1/Cables/dp0_cable0", "@odata.type": "#Cable.v1_0_0.Cable", "CableType": "", "Id": "dp0_cable0", "Name": "Cable" } $ curl -k -X GET https://{$bmc}/redfish/v1/Cables/dp0_cable1 { "@odata.id": "/redfish/v1/Cables/dp0_cable1", "@odata.type": "#Cable.v1_0_0.Cable", "CableType": "", "Id": "dp0_cable1", "Name": "Cable" } Set Length property to 1.5 meters using busctl, and check the properties busctl set-property xyz.openbmc_project.Inventory.Manager \ /xyz/openbmc_project/inventory/cables/dp0_cable0 \ xyz.openbmc_project.Inventory.Item.Cable Length d 1.5 $ curl -k -X GET https://{$bmc}/redfish/v1/Cables/dp0_cable0 { "@odata.id": "/redfish/v1/Cables/dp0_cable0", "@odata.type": "#Cable.v1_0_0.Cable", "CableType": "", "Id": "dp0_cable0", "LengthMeters": 1.5, "Name": "Cable" } Signed-off-by: Shantappa Teekappanavar <sbteeks@yahoo.com> Change-Id: I832ff1c1053f4d8100d04a42cc8046a61e8c1613
Diffstat (limited to 'redfish-core')
-rw-r--r--redfish-core/include/redfish.hpp3
-rw-r--r--redfish-core/lib/cable.hpp184
-rw-r--r--redfish-core/lib/service_root.hpp4
3 files changed, 190 insertions, 1 deletions
diff --git a/redfish-core/include/redfish.hpp b/redfish-core/include/redfish.hpp
index 2397df6a81..a9704d6aac 100644
--- a/redfish-core/include/redfish.hpp
+++ b/redfish-core/include/redfish.hpp
@@ -17,6 +17,7 @@
#include "../lib/account_service.hpp"
#include "../lib/bios.hpp"
+#include "../lib/cable.hpp"
#include "../lib/certificate_service.hpp"
#include "../lib/chassis.hpp"
#include "../lib/ethernet.hpp"
@@ -86,6 +87,8 @@ class RedfishService
requestRoutesStorageCollection(app);
requestRoutesStorage(app);
requestRoutesDrive(app);
+ requestRoutesCable(app);
+ requestRoutesCableCollection(app);
#ifdef BMCWEB_INSECURE_ENABLE_REDFISH_FW_TFTP_UPDATE
requestRoutesUpdateServiceActionsSimpleUpdate(app);
#endif
diff --git a/redfish-core/lib/cable.hpp b/redfish-core/lib/cable.hpp
new file mode 100644
index 0000000000..05da5f61ae
--- /dev/null
+++ b/redfish-core/lib/cable.hpp
@@ -0,0 +1,184 @@
+#pragma once
+#include <boost/container/flat_map.hpp>
+#include <utils/json_utils.hpp>
+
+namespace redfish
+{
+/**
+ * @brief Fill cable specific properties.
+ * @param[in,out] resp HTTP response.
+ * @param[in] ec Error code corresponding to Async method call.
+ * @param[in] properties List of Cable Properties key/value pairs.
+ */
+inline void
+ fillCableProperties(crow::Response& resp,
+ const boost::system::error_code ec,
+ const dbus::utility::DBusPropertiesMap& properties)
+{
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
+ messages::internalError(resp);
+ return;
+ }
+
+ for (const auto& [propKey, propVariant] : properties)
+ {
+ if (propKey == "CableTypeDescription")
+ {
+ const std::string* cableTypeDescription =
+ std::get_if<std::string>(&propVariant);
+ if (cableTypeDescription == nullptr)
+ {
+ messages::internalError(resp);
+ return;
+ }
+ resp.jsonValue["CableType"] = *cableTypeDescription;
+ }
+ else if (propKey == "Length")
+ {
+ const double* cableLength = std::get_if<double>(&propVariant);
+ if (cableLength == nullptr)
+ {
+ messages::internalError(resp);
+ return;
+ }
+
+ if (!std::isfinite(*cableLength))
+ {
+ if (std::isnan(*cableLength))
+ {
+ continue;
+ }
+ messages::internalError(resp);
+ return;
+ }
+
+ resp.jsonValue["LengthMeters"] = *cableLength;
+ }
+ }
+}
+
+/**
+ * @brief Api to get Cable properties.
+ * @param[in,out] asyncResp Async HTTP response.
+ * @param[in] cableObjectPath Object path of the Cable.
+ * @param[in] serviceMap A map to hold Service and corresponding
+ * interface list for the given cable id.
+ */
+inline void
+ getCableProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& cableObjectPath,
+ const dbus::utility::MapperServiceMap& serviceMap)
+{
+ BMCWEB_LOG_DEBUG << "Get Properties for cable " << cableObjectPath;
+
+ for (const auto& [service, interfaces] : serviceMap)
+ {
+ for (const auto& interface : interfaces)
+ {
+ if (interface != "xyz.openbmc_project.Inventory.Item.Cable")
+ {
+ continue;
+ }
+
+ crow::connections::systemBus->async_method_call(
+ [asyncResp](
+ const boost::system::error_code ec,
+ const dbus::utility::DBusPropertiesMap& properties) {
+ fillCableProperties(asyncResp->res, ec, properties);
+ },
+ service, cableObjectPath, "org.freedesktop.DBus.Properties",
+ "GetAll", interface);
+ }
+ }
+}
+
+/**
+ * The Cable schema
+ */
+inline void requestRoutesCable(App& app)
+{
+ BMCWEB_ROUTE(app, "/redfish/v1/Cables/<str>/")
+ .privileges(redfish::privileges::getCable)
+ .methods(boost::beast::http::verb::get)(
+ [](const crow::Request&,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& cableId) {
+ BMCWEB_LOG_DEBUG << "Cable Id: " << cableId;
+ auto respHandler =
+ [asyncResp,
+ cableId](const boost::system::error_code ec,
+ const dbus::utility::MapperGetSubTreeResponse&
+ subtree) {
+ if (ec.value() == EBADR)
+ {
+ messages::resourceNotFound(
+ asyncResp->res, "#Cable.v1_0_0.Cable", cableId);
+ return;
+ }
+
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR << "DBUS response error " << ec;
+ messages::internalError(asyncResp->res);
+ return;
+ }
+
+ for (const auto& [objectPath, serviceMap] : subtree)
+ {
+ sdbusplus::message::object_path path(objectPath);
+ if (path.filename() != cableId)
+ {
+ continue;
+ }
+
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#Cable.v1_0_0.Cable";
+ asyncResp->res.jsonValue["@odata.id"] =
+ "/redfish/v1/Cables/" + cableId;
+ asyncResp->res.jsonValue["Id"] = cableId;
+ asyncResp->res.jsonValue["Name"] = "Cable";
+
+ getCableProperties(asyncResp, objectPath,
+ serviceMap);
+ return;
+ }
+ messages::resourceNotFound(asyncResp->res, "Cable",
+ cableId);
+ };
+
+ crow::connections::systemBus->async_method_call(
+ respHandler, "xyz.openbmc_project.ObjectMapper",
+ "/xyz/openbmc_project/object_mapper",
+ "xyz.openbmc_project.ObjectMapper", "GetSubTree",
+ "/xyz/openbmc_project/inventory", 0,
+ std::array<const char*, 1>{
+ "xyz.openbmc_project.Inventory.Item.Cable"});
+ });
+}
+
+/**
+ * Collection of Cable resource instances
+ */
+inline void requestRoutesCableCollection(App& app)
+{
+ BMCWEB_ROUTE(app, "/redfish/v1/Cables/")
+ .privileges(redfish::privileges::getCableCollection)
+ .methods(boost::beast::http::verb::get)(
+ [](const crow::Request&,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#CableCollection.CableCollection";
+ asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Cables";
+ asyncResp->res.jsonValue["Name"] = "Cable Collection";
+ asyncResp->res.jsonValue["Description"] =
+ "Collection of Cable Entries";
+
+ collection_util::getCollectionMembers(
+ asyncResp, "/redfish/v1/Cables",
+ {"xyz.openbmc_project.Inventory.Item.Cable"});
+ });
+}
+
+} // namespace redfish
diff --git a/redfish-core/lib/service_root.hpp b/redfish-core/lib/service_root.hpp
index 63cc2109ea..62be63ff76 100644
--- a/redfish-core/lib/service_root.hpp
+++ b/redfish-core/lib/service_root.hpp
@@ -29,7 +29,8 @@ inline void
{
std::string uuid = persistent_data::getConfig().systemUuid;
- asyncResp->res.jsonValue["@odata.type"] = "#ServiceRoot.v1_5_0.ServiceRoot";
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#ServiceRoot.v1_11_0.ServiceRoot";
asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1";
asyncResp->res.jsonValue["Id"] = "RootService";
asyncResp->res.jsonValue["Name"] = "Root Service";
@@ -62,6 +63,7 @@ inline void
{"@odata.id", "/redfish/v1/EventService"}};
asyncResp->res.jsonValue["TelemetryService"] = {
{"@odata.id", "/redfish/v1/TelemetryService"}};
+ asyncResp->res.jsonValue["Cables"] = {{"@odata.id", "/redfish/v1/Cables"}};
}
inline void requestRoutesServiceRoot(App& app)