blob: c5203409ea36ba0497e508ac92b8a52f58bc0668 [file] [log] [blame]
#include "pldm.hpp"
#include <libpldm/entity.h>
#include <libpldm/platform.h>
#include <libpldm/state_set.h>
#include <phosphor-logging/log.hpp>
namespace pldm
{
using sdbusplus::exception::SdBusError;
using namespace phosphor::logging;
void Interface::fetchOCCSensorInfo(const PdrList& pdrs,
SensorToOCCInstance& sensorInstanceMap,
SensorOffset& sensorOffset)
{
bool offsetFound = false;
auto pdr =
reinterpret_cast<const pldm_state_sensor_pdr*>(pdrs.front().data());
auto possibleStatesPtr = pdr->possible_states;
for (auto offset = 0; offset < pdr->composite_sensor_count; offset++)
{
auto possibleStates =
reinterpret_cast<const state_sensor_possible_states*>(
possibleStatesPtr);
if (possibleStates->state_set_id ==
PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS)
{
sensorOffset = offset;
offsetFound = true;
break;
}
possibleStatesPtr += sizeof(possibleStates->state_set_id) +
sizeof(possibleStates->possible_states_size) +
possibleStates->possible_states_size;
}
if (!offsetFound)
{
log<level::ERR>("pldm: OCC state sensor PDR with StateSetId "
"PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS not found");
return;
}
// To order SensorID based on the EntityInstance
std::map<EntityInstance, SensorID> entityInstMap{};
for (auto& pdr : pdrs)
{
auto pdrPtr =
reinterpret_cast<const pldm_state_sensor_pdr*>(pdr.data());
entityInstMap.emplace(
static_cast<EntityInstance>(pdrPtr->entity_instance),
static_cast<SensorID>(pdrPtr->sensor_id));
}
open_power::occ::instanceID count = start;
for (auto const& pair : entityInstMap)
{
sensorInstanceMap.emplace(pair.second, count);
count++;
}
}
void Interface::sensorEvent(sdbusplus::message::message& msg)
{
if (!isOCCSensorCacheValid())
{
PdrList pdrs{};
try
{
auto method = bus.new_method_call(
"xyz.openbmc_project.PLDM", "/xyz/openbmc_project/pldm",
"xyz.openbmc_project.PLDM.PDR", "FindStateSensorPDR");
method.append(tid, (uint16_t)PLDM_ENTITY_PROC_MODULE,
(uint16_t)PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS);
auto responseMsg = bus.call(method);
responseMsg.read(pdrs);
}
catch (const SdBusError& e)
{
log<level::ERR>("pldm: Failed to fetch the OCC state sensor PDRs",
entry("ERROR=%s", e.what()));
}
if (!pdrs.size())
{
log<level::ERR>("pldm: OCC state sensor PDRs not present");
return;
}
fetchOCCSensorInfo(pdrs, sensorToOCCInstance, sensorOffset);
}
TerminusID tid{};
SensorID sensorId{};
SensorOffset msgSensorOffset{};
EventState eventState{};
EventState previousEventState{};
msg.read(tid, sensorId, sensorOffset, eventState, previousEventState);
auto sensorEntry = sensorToOCCInstance.find(sensorId);
if (sensorEntry == sensorToOCCInstance.end() ||
(msgSensorOffset != sensorOffset))
{
// No action for non matching sensorEvents
return;
}
bool newState{};
if (eventState == static_cast<EventState>(
PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_IN_SERVICE))
{
newState = callBack(sensorEntry->second, true);
}
else if (eventState ==
static_cast<EventState>(
PLDM_STATE_SET_OPERATIONAL_RUNNING_STATUS_STOPPED))
{
newState = callBack(sensorEntry->second, false);
}
else
{
return;
}
log<level::INFO>("pldm: Updated OCCActive state",
entry("STATE=%s", newState ? "true" : "false"));
return;
}
void Interface::hostStateEvent(sdbusplus::message::message& msg)
{
std::map<std::string, std::variant<std::string>> properties{};
std::string interface;
msg.read(interface, properties);
const auto stateEntry = properties.find("CurrentHostState");
if (stateEntry != properties.end())
{
auto stateEntryValue = stateEntry->second;
auto propVal = std::get<std::string>(stateEntryValue);
if (propVal == "xyz.openbmc_project.State.Host.HostState.Off")
{
sensorToOCCInstance.clear();
}
}
}
} // namespace pldm