blob: 7e5e491bbe662d4e5b831172dcf45100aeea308a [file] [log] [blame]
#include "pdr.hpp"
#include <libpldm/platform.h>
#include <phosphor-logging/lg2.hpp>
#include <climits>
PHOSPHOR_LOG2_USING;
using namespace pldm::pdr;
namespace pldm
{
namespace responder
{
namespace pdr_utils
{
pldm_pdr* Repo::getPdr() const
{
return repo;
}
RecordHandle Repo::addRecord(const PdrEntry& pdrEntry)
{
uint32_t handle = pdrEntry.handle.recordHandle;
int rc = pldm_pdr_add_check(repo, pdrEntry.data, pdrEntry.size, false,
TERMINUS_HANDLE, &handle);
if (rc)
{
// pldm_pdr_add() assert()ed on failure to add PDR
throw std::runtime_error("Failed to add PDR");
}
return handle;
}
const pldm_pdr_record* Repo::getFirstRecord(PdrEntry& pdrEntry)
{
constexpr uint32_t firstNum = 0;
uint8_t* pdrData = nullptr;
auto record = pldm_pdr_find_record(getPdr(), firstNum, &pdrData,
&pdrEntry.size,
&pdrEntry.handle.nextRecordHandle);
if (record)
{
pdrEntry.data = pdrData;
}
return record;
}
const pldm_pdr_record* Repo::getNextRecord(const pldm_pdr_record* currRecord,
PdrEntry& pdrEntry)
{
uint8_t* pdrData = nullptr;
auto record = pldm_pdr_get_next_record(getPdr(), currRecord, &pdrData,
&pdrEntry.size,
&pdrEntry.handle.nextRecordHandle);
if (record)
{
pdrEntry.data = pdrData;
}
return record;
}
uint32_t Repo::getRecordHandle(const pldm_pdr_record* record) const
{
return pldm_pdr_get_record_handle(getPdr(), record);
}
uint32_t Repo::getRecordCount()
{
return pldm_pdr_get_record_count(getPdr());
}
bool Repo::empty()
{
return !getRecordCount();
}
StatestoDbusVal populateMapping(const std::string& type, const Json& dBusValues,
const PossibleValues& pv)
{
size_t pos = 0;
pldm::utils::PropertyValue value;
StatestoDbusVal valueMap;
if (dBusValues.size() != pv.size())
{
error(
"dBusValues size is not equal to pv size, dBusValues Size: {DBUS_VAL_SIZE}, pv Size: {PV_SIZE}",
"DBUS_VAL_SIZE", dBusValues.size(), "PV_SIZE", pv.size());
return {};
}
for (auto it = dBusValues.begin(); it != dBusValues.end(); ++it, ++pos)
{
if (type == "uint8_t")
{
value = static_cast<uint8_t>(it.value());
}
else if (type == "uint16_t")
{
value = static_cast<uint16_t>(it.value());
}
else if (type == "uint32_t")
{
value = static_cast<uint32_t>(it.value());
}
else if (type == "uint64_t")
{
value = static_cast<uint64_t>(it.value());
}
else if (type == "int16_t")
{
value = static_cast<int16_t>(it.value());
}
else if (type == "int32_t")
{
value = static_cast<int32_t>(it.value());
}
else if (type == "int64_t")
{
value = static_cast<int64_t>(it.value());
}
else if (type == "bool")
{
value = static_cast<bool>(it.value());
}
else if (type == "double")
{
value = static_cast<double>(it.value());
}
else if (type == "string")
{
value = static_cast<std::string>(it.value());
}
else
{
error("Unknown D-Bus property type, TYPE={OTHER_TYPE}",
"OTHER_TYPE", type.c_str());
return {};
}
valueMap.emplace(pv[pos], value);
}
return valueMap;
}
std::tuple<TerminusHandle, SensorID, SensorInfo>
parseStateSensorPDR(const std::vector<uint8_t>& stateSensorPdr)
{
auto pdr =
reinterpret_cast<const pldm_state_sensor_pdr*>(stateSensorPdr.data());
CompositeSensorStates sensors{};
auto statesPtr = pdr->possible_states;
auto compositeSensorCount = pdr->composite_sensor_count;
while (compositeSensorCount--)
{
auto state =
reinterpret_cast<const state_sensor_possible_states*>(statesPtr);
PossibleStates possibleStates{};
uint8_t possibleStatesPos{};
auto updateStates =
[&possibleStates, &possibleStatesPos](const bitfield8_t& val) {
for (int i = 0; i < CHAR_BIT; i++)
{
if (val.byte & (1 << i))
{
possibleStates.insert(possibleStatesPos * CHAR_BIT + i);
}
}
possibleStatesPos++;
};
std::for_each(&state->states[0],
&state->states[state->possible_states_size],
updateStates);
sensors.emplace_back(std::move(possibleStates));
if (compositeSensorCount)
{
statesPtr += sizeof(state_sensor_possible_states) +
state->possible_states_size - 1;
}
}
auto entityInfo =
std::make_tuple(static_cast<ContainerID>(pdr->container_id),
static_cast<EntityType>(pdr->entity_type),
static_cast<EntityInstance>(pdr->entity_instance));
auto sensorInfo = std::make_tuple(std::move(entityInfo),
std::move(sensors));
return std::make_tuple(pdr->terminus_handle, pdr->sensor_id,
std::move(sensorInfo));
}
} // namespace pdr_utils
} // namespace responder
} // namespace pldm