blob: 25ca51ed51dac181ea0b0780f8dff6ab9189e232 [file] [log] [blame]
#pragma once
#include "config.h"
#include "common/utils.hpp"
#include "libpldmresponder/pdr.hpp"
#include "pdr_utils.hpp"
#include "pldmd/handler.hpp"
#include <libpldm/platform.h>
#include <libpldm/states.h>
#include <cstdint>
#include <map>
namespace pldm
{
namespace responder
{
namespace platform_state_sensor
{
/** @brief Function to get the sensor state
*
* @tparam[in] DBusInterface - DBus interface type
* @param[in] dBusIntf - The interface object of DBusInterface
* @param[in] stateToDbusValue - Map of DBus property State to attribute value
* @param[in] dbusMapping - The d-bus object
*
* @return - Enumeration of SensorState
*/
template <class DBusInterface>
uint8_t getStateSensorEventState(
const DBusInterface& dBusIntf,
const std::map<pldm::responder::pdr_utils::State,
pldm::utils::PropertyValue>& stateToDbusValue,
const pldm::utils::DBusMapping& dbusMapping)
{
try
{
auto propertyValue = dBusIntf.getDbusPropertyVariant(
dbusMapping.objectPath.c_str(), dbusMapping.propertyName.c_str(),
dbusMapping.interface.c_str());
for (const auto& stateValue : stateToDbusValue)
{
if (stateValue.second == propertyValue)
{
return stateValue.first;
}
}
}
catch (const std::exception& e)
{
std::cerr << "Get StateSensor EventState from dbus Error, interface : "
<< dbusMapping.objectPath.c_str()
<< " ,exception : " << e.what() << '\n';
}
return PLDM_SENSOR_UNKNOWN;
}
/** @brief Function to get the state sensor readings requested by pldm requester
*
* @tparam[in] DBusInterface - DBus interface type
* @tparam[in] Handler - pldm::responder::platform::Handler
* @param[in] dBusIntf - The interface object of DBusInterface
* @param[in] handler - The interface object of
* pldm::responder::platform::Handler
* @param[in] sensorId - Sensor ID sent by the requester to act on
* @param[in] sensorRearmCnt - Each bit location in this field corresponds to a
* particular sensor within the state sensor
* @param[out] compSensorCnt - composite sensor count
* @param[out] stateField - The state field data for each of the states,
* equal to composite sensor count in number
* @return - Success or failure in setting the states. Returns failure in
* terms of PLDM completion codes if atleast one state fails to be set
*/
template <class DBusInterface, class Handler>
int getStateSensorReadingsHandler(
const DBusInterface& dBusIntf, Handler& handler, uint16_t sensorId,
uint8_t sensorRearmCnt, uint8_t& compSensorCnt,
std::vector<get_sensor_state_field>& stateField)
{
using namespace pldm::responder::pdr;
using namespace pldm::utils;
pldm_state_sensor_pdr* pdr = nullptr;
std::unique_ptr<pldm_pdr, decltype(&pldm_pdr_destroy)> stateSensorPdrRepo(
pldm_pdr_init(), pldm_pdr_destroy);
pldm::responder::pdr_utils::Repo stateSensorPDRs(stateSensorPdrRepo.get());
getRepoByType(handler.getRepo(), stateSensorPDRs, PLDM_STATE_SENSOR_PDR);
if (stateSensorPDRs.empty())
{
std::cerr << "Failed to get record by PDR type\n";
return PLDM_PLATFORM_INVALID_SENSOR_ID;
}
pldm::responder::pdr_utils::PdrEntry pdrEntry{};
auto pdrRecord = stateSensorPDRs.getFirstRecord(pdrEntry);
while (pdrRecord)
{
pdr = reinterpret_cast<pldm_state_sensor_pdr*>(pdrEntry.data);
assert(pdr != NULL);
if (pdr->sensor_id != sensorId)
{
pdr = nullptr;
pdrRecord = stateSensorPDRs.getNextRecord(pdrRecord, pdrEntry);
continue;
}
compSensorCnt = pdr->composite_sensor_count;
if (sensorRearmCnt > compSensorCnt)
{
std::cerr << "The requester sent wrong sensorRearm"
<< " count for the sensor, SENSOR_ID=" << sensorId
<< "SENSOR_REARM_COUNT=" << sensorRearmCnt << "\n";
return PLDM_PLATFORM_REARM_UNAVAILABLE_IN_PRESENT_STATE;
}
if (sensorRearmCnt == 0)
{
sensorRearmCnt = compSensorCnt;
stateField.resize(sensorRearmCnt);
}
break;
}
if (!pdr)
{
return PLDM_PLATFORM_INVALID_SENSOR_ID;
}
int rc = PLDM_SUCCESS;
try
{
const auto& [dbusMappings, dbusValMaps] = handler.getDbusObjMaps(
sensorId, pldm::responder::pdr_utils::TypeId::PLDM_SENSOR_ID);
stateField.clear();
for (size_t i = 0; i < sensorRearmCnt; i++)
{
auto& dbusMapping = dbusMappings[i];
uint8_t sensorEvent = getStateSensorEventState<DBusInterface>(
dBusIntf, dbusValMaps[i], dbusMapping);
uint8_t opState = PLDM_SENSOR_ENABLED;
if (sensorEvent == PLDM_SENSOR_UNKNOWN)
{
opState = PLDM_SENSOR_UNAVAILABLE;
}
stateField.push_back({opState, PLDM_SENSOR_NORMAL,
PLDM_SENSOR_UNKNOWN, sensorEvent});
}
}
catch (const std::out_of_range& e)
{
std::cerr << "the sensorId does not exist. sensor id: " << sensorId
<< e.what() << '\n';
rc = PLDM_ERROR;
}
return rc;
}
} // namespace platform_state_sensor
} // namespace responder
} // namespace pldm