diff options
author | Shantappa Teekappanavar <sbteeks@yahoo.com> | 2021-12-17 04:02:52 +0300 |
---|---|---|
committer | Ed Tanous <ed@tanous.net> | 2022-01-26 21:27:54 +0300 |
commit | 9c929bea78857633f2b71b356abf4aa4b1ac56d2 (patch) | |
tree | 33c1dc9af157337eebf9589900a3406d777d4c55 /redfish-core | |
parent | 71b861b64bde714410c4fe94f1628a70cb6b17aa (diff) | |
download | bmcweb-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.hpp | 3 | ||||
-rw-r--r-- | redfish-core/lib/cable.hpp | 184 | ||||
-rw-r--r-- | redfish-core/lib/service_root.hpp | 4 |
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) |