Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 101 additions & 6 deletions redfish-core/lib/assembly.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
#include <utility>
#include <vector>

static constexpr const char* readyToRemoveIface =
"xyz.openbmc_project.State.ReadyToRemove";
namespace redfish
{

Expand Down Expand Up @@ -152,6 +154,32 @@ void getAssemblyHealth(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
});
}

/**
* @brief Populate ReadyToRemove for assemblies that implement
* xyz.openbmc_project.State.ReadyToRemove.
*/
inline void getAssemblyReadyToRemove(
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& serviceName, const std::string& assembly,
const nlohmann::json::json_pointer& assemblyJsonPtr)
{
dbus::utility::getProperty<bool>(
serviceName, assembly, readyToRemoveIface, "ReadyToRemove",
[asyncResp,
assemblyJsonPtr](const boost::system::error_code& ec, bool value) {
if (ec)
{
if (ec.value() != EBADR)
{
BMCWEB_LOG_ERROR("DBUS response error: {}", ec.value());
messages::internalError(asyncResp->res);
}
return;
}
asyncResp->res.jsonValue[assemblyJsonPtr]["ReadyToRemove"] = value;
});
}

inline void afterGetDbusObject(
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& assembly,
Expand Down Expand Up @@ -197,6 +225,11 @@ inline void afterGetDbusObject(
getAssemblyHealth(asyncResp, serviceName, assembly,
assemblyJsonPtr);
}
else if (interface == readyToRemoveIface)
{
getAssemblyReadyToRemove(asyncResp, serviceName, assembly,
assemblyJsonPtr);
}
}
}
}
Expand All @@ -219,7 +252,7 @@ inline void getAssemblyProperties(
for (const std::string& assembly : assemblies)
{
nlohmann::json::object_t item;
item["@odata.type"] = "#Assembly.v1_5_1.AssemblyData";
item["@odata.type"] = "#Assembly.v1_6_0.AssemblyData";
item["@odata.id"] = boost::urls::format(
"/redfish/v1/Chassis/{}/Assembly#/Assemblies/{}", chassisId,
std::to_string(assemblyIndex));
Expand Down Expand Up @@ -358,16 +391,19 @@ inline void afterHandleChassisAssemblyPatch(
}

std::map<std::string, bool> locationIndicatorActiveMap;
std::map<std::string, bool> readyToRemoveMap;
std::map<std::string, nlohmann::json> oemIndicatorMap;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed offline, you can keep OemIndicatorMap as is and, just add the readyToRemoveMap to use it for our usecase (line 394)

We can move from the existing Oem property to use the standard redfish for batteryCM in another PR.
@gtmills ^

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

retained handling of oem/openbmc/readytoremove for tod battery and panels, added separate handling for readytoremove


for (nlohmann::json::object_t& item : assemblyData)
{
std::optional<std::string> memberId;
std::optional<bool> locationIndicatorActive;
std::optional<bool> readyToRemove;
std::optional<nlohmann::json> oem;
if (!json_util::readJsonObject(item, asyncResp->res, "MemberId",
memberId, "LocationIndicatorActive",
locationIndicatorActive, "Oem", oem))
if (!json_util::readJsonObject(
item, asyncResp->res, "MemberId", memberId,
"LocationIndicatorActive", locationIndicatorActive,
"ReadyToRemove", readyToRemove, "Oem", oem))
{
return;
}
Expand All @@ -386,6 +422,20 @@ inline void afterHandleChassisAssemblyPatch(
return;
}
}
if (readyToRemove)
{
if (memberId)
{
readyToRemoveMap[*memberId] = *readyToRemove;
}
else
{
BMCWEB_LOG_WARNING(
"Property Missing - MemberId must be included with ReadyToRemove");
messages::propertyMissing(asyncResp->res, "MemberId");
return;
}
}
if (oem)
{
if (memberId)
Expand Down Expand Up @@ -413,6 +463,7 @@ inline void afterHandleChassisAssemblyPatch(
setLocationIndicatorActive(asyncResp, assembly, iter->second);
}

// Handle Oem/OpenBMC/ReadyToRemove
auto iter2 = oemIndicatorMap.find(std::to_string(assemblyIndex));

if (iter2 != oemIndicatorMap.end())
Expand Down Expand Up @@ -492,6 +543,46 @@ inline void afterHandleChassisAssemblyPatch(
return;
}
}

// Handle top-level ReadyToRemove (standard Assembly schema v1_6_0)
auto iter3 = readyToRemoveMap.find(std::to_string(assemblyIndex));

if (iter3 != readyToRemoveMap.end())
{
bool readytoremove = iter3->second;

constexpr std::array<std::string_view, 1> rtrIface = {
readyToRemoveIface};
dbus::utility::getDbusObject(
assembly, rtrIface,
[asyncResp, assembly,
readytoremove](const boost::system::error_code& ec1,
const dbus::utility::MapperGetObject& object) {
if (ec1 || object.empty())
{
BMCWEB_LOG_ERROR(
"getDbusObject failed for ReadyToRemove on {}: {}",
assembly, ec1.message());
messages::internalError(asyncResp->res);
return;
}

const std::string& service = object.begin()->first;
sdbusplus::asio::setProperty(
*crow::connections::systemBus, service, assembly,
readyToRemoveIface, "ReadyToRemove", readytoremove,
[asyncResp](const boost::system::error_code& ec2) {
if (ec2)
{
BMCWEB_LOG_ERROR(
"Failed to set ReadyToRemove: {}",
ec2.message());
messages::internalError(asyncResp->res);
}
});
});
}

assemblyIndex++;
}
}
Expand All @@ -515,8 +606,12 @@ inline void handleChassisAssemblyPatch(

assembly_utils::getChassisAssembly(
asyncResp, chassisID,
std::bind_front(afterHandleChassisAssemblyPatch, asyncResp, chassisID,
assemblyData));
[asyncResp, chassisID, assemblyData = std::move(assemblyData)](
const boost::system::error_code& ec,
const std::vector<std::string>& assemblyList) mutable {
afterHandleChassisAssemblyPatch(asyncResp, chassisID, assemblyData,
ec, assemblyList);
});
}

/**
Expand Down
Empty file added res,
Empty file.