#include "event_parser.hpp" | |
#include <filesystem> | |
#include <fstream> | |
#include <iostream> | |
#include <set> | |
#include <xyz/openbmc_project/Common/error.hpp> | |
namespace pldm::responder::events | |
{ | |
namespace fs = std::filesystem; | |
using InternalFailure = | |
sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure; | |
const Json emptyJson{}; | |
const std::vector<Json> emptyJsonList{}; | |
const std::vector<std::string> emptyStringVec{}; | |
constexpr auto eventStateSensorJson = "event_state_sensor.json"; | |
const std::set<std::string_view> supportedDbusPropertyTypes = { | |
"bool", "uint8_t", "int16_t", "uint16_t", "int32_t", | |
"uint32_t", "int64_t", "uint64_t", "double", "string"}; | |
StateSensorHandler::StateSensorHandler(const std::string& dirPath) | |
{ | |
fs::path dir(dirPath); | |
if (!fs::exists(dir) || fs::is_empty(dir)) | |
{ | |
std::cerr << "Event config directory does not exist or empty, DIR=" | |
<< dirPath << "\n"; | |
return; | |
} | |
fs::path filePath = dir / eventStateSensorJson; | |
if (!fs::exists(filePath)) | |
{ | |
std::cerr << "Event state sensor JSON does not exist, PATH=" << filePath | |
<< "\n"; | |
throw InternalFailure(); | |
} | |
std::ifstream jsonFile(filePath); | |
auto data = Json::parse(jsonFile, nullptr, false); | |
if (data.is_discarded()) | |
{ | |
std::cerr << "Parsing Event state sensor JSON file failed, FILE=" | |
<< filePath; | |
throw InternalFailure(); | |
} | |
auto entries = data.value("entries", emptyJsonList); | |
for (const auto& entry : entries) | |
{ | |
StateSensorEntry stateSensorEntry{}; | |
stateSensorEntry.containerId = | |
static_cast<uint16_t>(entry.value("containerID", 0)); | |
stateSensorEntry.entityType = | |
static_cast<uint16_t>(entry.value("entityType", 0)); | |
stateSensorEntry.entityInstance = | |
static_cast<uint16_t>(entry.value("entityInstance", 0)); | |
stateSensorEntry.sensorOffset = | |
static_cast<uint8_t>(entry.value("sensorOffset", 0)); | |
pldm::utils::DBusMapping dbusInfo{}; | |
auto dbus = entry.value("dbus", emptyJson); | |
dbusInfo.objectPath = dbus.value("object_path", ""); | |
dbusInfo.interface = dbus.value("interface", ""); | |
dbusInfo.propertyName = dbus.value("property_name", ""); | |
dbusInfo.propertyType = dbus.value("property_type", ""); | |
if (dbusInfo.objectPath.empty() || dbusInfo.interface.empty() || | |
dbusInfo.propertyName.empty() || | |
(supportedDbusPropertyTypes.find(dbusInfo.propertyType) == | |
supportedDbusPropertyTypes.end())) | |
{ | |
std::cerr << "Invalid dbus config," | |
<< " OBJPATH=" << dbusInfo.objectPath << " INTERFACE=" | |
<< dbusInfo.interface << " PROPERTY_NAME=" | |
<< dbusInfo.propertyName | |
<< " PROPERTY_TYPE=" << dbusInfo.propertyType << "\n"; | |
continue; | |
} | |
auto eventStates = entry.value("event_states", emptyJsonList); | |
auto propertyValues = dbus.value("property_values", emptyJsonList); | |
if ((eventStates.size() == 0) || (propertyValues.size() == 0) || | |
(eventStates.size() != propertyValues.size())) | |
{ | |
std::cerr << "Invalid event state JSON config," | |
<< " EVENT_STATE_SIZE=" << eventStates.size() | |
<< " PROPERTY_VALUE_SIZE=" << propertyValues.size() | |
<< "\n"; | |
continue; | |
} | |
auto eventStateMap = mapStateToDBusVal(eventStates, propertyValues, | |
dbusInfo.propertyType); | |
eventMap.emplace( | |
stateSensorEntry, | |
std::make_tuple(std::move(dbusInfo), std::move(eventStateMap))); | |
} | |
} | |
StateToDBusValue StateSensorHandler::mapStateToDBusVal( | |
const Json& eventStates, const Json& propertyValues, std::string_view type) | |
{ | |
StateToDBusValue eventStateMap{}; | |
auto stateIt = eventStates.begin(); | |
auto propIt = propertyValues.begin(); | |
for (; stateIt != eventStates.end(); ++stateIt, ++propIt) | |
{ | |
auto propValue = utils::jsonEntryToDbusVal(type, propIt.value()); | |
eventStateMap.emplace((*stateIt).get<uint8_t>(), std::move(propValue)); | |
} | |
return eventStateMap; | |
} | |
int StateSensorHandler::eventAction(const StateSensorEntry& entry, | |
pdr::EventState state) | |
{ | |
try | |
{ | |
const auto& [dbusMapping, eventStateMap] = eventMap.at(entry); | |
utils::PropertyValue propValue{}; | |
try | |
{ | |
propValue = eventStateMap.at(state); | |
} | |
catch (const std::out_of_range& e) | |
{ | |
std::cerr << "Invalid event state" << static_cast<unsigned>(state) | |
<< '\n'; | |
return PLDM_ERROR_INVALID_DATA; | |
} | |
try | |
{ | |
pldm::utils::DBusHandler().setDbusProperty(dbusMapping, propValue); | |
} | |
catch (const std::exception& e) | |
{ | |
std::cerr << "Error setting property, ERROR=" << e.what() | |
<< " PROPERTY=" << dbusMapping.propertyName | |
<< " INTERFACE=" << dbusMapping.interface << " PATH=" | |
<< dbusMapping.objectPath << "\n"; | |
return PLDM_ERROR; | |
} | |
} | |
catch (const std::out_of_range& e) | |
{ | |
// There is no BMC action for this PLDM event | |
return PLDM_SUCCESS; | |
} | |
return PLDM_SUCCESS; | |
} | |
} // namespace pldm::responder::events |