blob: 98fea8e0a0635e00f1c2937eb4232fc3aa8f0edf [file] [log] [blame]
#pragma once
#include "async_resp.hpp"
#include "dbus_utility.hpp"
#include "error_messages.hpp"
#include "managed_store.hpp"
#include "utility.hpp"
#include <array>
#include <string_view>
#include <unordered_map>
#ifdef UNIT_TEST_BUILD
#include "test/g3/mock_managed_store.hpp" // NOLINT
#endif
namespace redfish
{
namespace fan_utils
{
constexpr std::array<std::string_view, 1> fanInterfaces = {
"xyz.openbmc_project.Configuration.Fan"};
inline void fillFanProperties(
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& objectPath,
const dbus::utility::DBusPropertiesMap& properties,
const std::shared_ptr<std::unordered_map<std::string, std::string>>&
fanSensorToInventoryPath)
{
for (const auto& [propKey, propVariant] : properties)
{
if (propKey == "TachSensor")
{
const std::string* tachSensor =
std::get_if<std::string>(&propVariant);
if (tachSensor == nullptr)
{
messages::internalError(asyncResp->res);
return;
}
(*fanSensorToInventoryPath)[*tachSensor] = objectPath;
}
else if (propKey == "PWMSensor")
{
const std::string* pwmSensor =
std::get_if<std::string>(&propVariant);
if (pwmSensor == nullptr)
{
messages::internalError(asyncResp->res);
return;
}
(*fanSensorToInventoryPath)[*pwmSensor] = objectPath;
}
}
}
template <typename Callback>
inline void getFanInventory(
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::shared_ptr<std::unordered_map<std::string, std::string>>&
fanSensorToInventoryPath,
Callback callback)
{
managedStore::ManagedObjectStoreContext requestContext(asyncResp);
managedStore::GetManagedObjectStore()->getSubTree(
"/xyz/openbmc_project/inventory", 0, fanInterfaces, requestContext,
[asyncResp, fanSensorToInventoryPath, requestContext,
callback{callback}](
const boost::system::error_code ec,
const dbus::utility::MapperGetSubTreeResponse& subtree) {
if (ec)
{
BMCWEB_LOG_DEBUG << "DBUS response error";
messages::internalError(asyncResp->res);
return;
}
if (subtree.empty())
{
callback();
return;
}
auto fanConfigurationsQueried = std::make_shared<int>(subtree.size());
for (const auto& [objectPath, serviceMap] : subtree)
{
for (const auto& [service, interfaces] : serviceMap)
{
for (const auto& interface : interfaces)
{
if (interface != fanInterfaces[0])
{
continue;
}
managedStore::GetManagedObjectStore()->getAllProperties(
service, objectPath, interface, requestContext,
[asyncResp, fanSensorToInventoryPath, objectPath,
callback, fanConfigurationsQueried](
const boost::system::error_code& ec,
const dbus::utility::DBusPropertiesMap&
properties) {
if (ec)
{
BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
messages::internalError(asyncResp->res);
return;
}
fillFanProperties(asyncResp, objectPath, properties,
fanSensorToInventoryPath);
if (*fanConfigurationsQueried <= 0)
{
BMCWEB_LOG_ERROR << "Unaccounted fan configuration";
messages::internalError(asyncResp->res);
return;
}
if (*fanConfigurationsQueried == 1)
{
callback();
}
--(*fanConfigurationsQueried);
});
}
}
}
});
}
inline void AddThermalSubsystemLink(
const sdbusplus::message::object_path& fanInventoryPath,
nlohmann::json& sensorJson)
{
nlohmann::json::object_t obj;
obj["@odata.id"] = crow::utility::urlFromPieces(
"redfish", "v1", "Chassis", fanInventoryPath.parent_path().filename(),
"ThermalSubsystem", "Fans", fanInventoryPath.filename());
sensorJson["RelatedItem"] = nlohmann::json::array_t{std::move(obj)};
}
inline void AddRelatedItemForFanSensor(
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& sensorName)
{
auto fanSensorToInventoryPath =
std::make_shared<std::unordered_map<std::string, std::string>>();
getFanInventory(asyncResp, fanSensorToInventoryPath,
[asyncResp, sensorName, fanSensorToInventoryPath]() {
auto findFanObjectPath = fanSensorToInventoryPath->find(sensorName);
if (findFanObjectPath != fanSensorToInventoryPath->end())
{
sdbusplus::message::object_path fanInventoryPath(
findFanObjectPath->second);
AddThermalSubsystemLink(fanInventoryPath, asyncResp->res.jsonValue);
}
});
}
} // namespace fan_utils
} // namespace redfish